# AGSL Quick Reference

AGSL is designed to be largely compatible with GLSL ES 1.0. For more information, see the equivalent function in the OpenGL ES Shading Language documentation. When possible, this documentation attempts to call out differences between AGSL and GLSL.

## Types

AGSL supports GLSL ES 1.0 types along with an additional way to represent vector and matrix types. AGSL supports additional short and half types to represent medium precision.

### Basic types

Type Description
void No function return value or empty parameter list. Unlike in GLSL, functions without a void return type must return a value.
bool, bvec2, bvec3, bvec4
(bool2, bool3, bool4).
Boolean scalar/vector
int, ivec2, ivec3, ivec4
(int2, int3, int4)
highp signed integer/vector
float, vec2, vec3, vec4
(float2, float3, float4)
highp (single precision) floating point scalar/vector
short, short2, short3, short4 equivalent to mediump int signed integer/vector
half, half2, half3, half4 equivalent to mediump float scalar/vector
mat2, mat3, mat4
(float2x2, float3x3, float4x4)
2x2, 3x3, 4x4 float matrix
half2x2, half3x3, half4x4 Equivalent to mediump float matrix types

### Precision and range minimums

These are the minimum guaranteed precision and range associated with each modifier based upon the OpenGL ES 2.0 specification. Since most devices support ES 3.0, they will have more guaranteed highp precision/range and int mediump range. Precision modifiers can be applied to scalar, vector, and matrix variables and parameters. Only the minimums listed below are guaranteed; lowp is not necessarily actually lower precision than mediump, and mediump is not necessarily lower precision than highp. AGSL currently converts lowp to mediump in the final output.

Modifier 'float' range 'float' magnitude range 'float' precision 'int' range
highp $$\left\{-2^{62},2^{62}\right\}$$ $$\left\{2^{-62},2^{62}\right\}$$ Relative: $$2^{-16}$$ $$\left\{-2^{16},2^{16}\right\}$$
mediump $$\left\{-2^{14},2^{14}\right\}$$ $$\left\{2^{-14},2^{14}\right\}$$ Relative: $$2^{-10}$$ $$\left\{-2^{10},2^{10}\right\}$$
lowp $$\left\{-2,2\right\}$$ $$\left\{2^{-8},2\right\}$$ Absolute: $$2^{-8}$$ $$\left\{-2^{8},2^{8}\right\}$$

In addition to array numeric subscript syntax ex: var[num], names of vector components for vectors of length 2 - 4 are denoted by a single letter. Components can be swizzled and replicated. ex:vect.yx,vect.yy

vect.xyzw - Use when accessing vectors that represent points/normals

vect.rgba - Use when accessing vectors that represent colors

vect.LTRB - Use when the vector represents a rectangle (not in GLSL)

In AGSL, 0 and 1 can be used to produce a constant 0 or 1 in that channel. Ex: vect.rgb1 == vec4(vect.rgb,1)

### Structures and arrays

Structures are declared with the same syntax as GLSL, but AGSL only supports structures at global scope.

struct type-name {
members
} struct-name; // optional variable declaration.


Only 1-dimensional arrays are supported with an explicit array size, using either C-style or GLSL style syntax:

<base type>[<array size>] variable name - ex: half[10] x;

<base type> variable name[<array size>] - ex: half x[10];

Arrays cannot be returned from a function, copied, assigned or compared. Array restrictions propagate out to structures containing arrays. Arrays can only be indexed using a constant or a loop variable.

## Qualifiers

Type Description
const Compile-time constant, or read-only function parameter.
uniform Value does not change across the primitive being processed. Uniforms are passed from Android using RuntimeShader methods for setColorUniform, setFloatUniform, setIntUniform, setInputBuffer, and setInputShader.
in For passed-in function parameters. This is the default.
out For passed-out function parameters. Must use the same precision as the function definition.
inout For parameters that are both passed in and out of a function. Must use the same precision as the function definition.

## Variable declaration

Declarations must be in an explicit braced scope. The declaration of y in the following sample is disallowed:

if (condition)
int y = 0;


## Matrix/structure/array basics

### Matrix constructor examples

When a matrix is constructed with a single value, all values along the diagonal are given that value, while the rest are given zeros. float2x2(1.0) would therefore create a 2x2 identity matrix.

When a matrix is constructed with multiple values, columns are filled first (column-major order).

Note that, unlike GLSL, constructors that reduce the number of components of a passed-in vector are not supported, but you can use swizzling to have the same effect. To construct a vec3 from a vec4 in AGSL with the same behavior as GLSL, specify vec3 nv = quadVec.xyz.

### Structure constructor example

struct light { float intensity; float3 pos; };
// literal integer constants auto-converted to floating point
light lightVar = light(3, float3(1, 2, 3.0));


### Matrix components

Access components of a matrix with array subscripting syntax.

float4x4 m; // represents a matrix
m[1] = float4(2.0); // sets second column to all 2.0
m[0][0] = 1.0; // sets upper left element to 1.0
m[2][3] = 2.0; // sets 4th element of 3rd column to 2.0


### Structure fields

Select structure fields using the period . operator. Operators include:

Operator Description
. field selector
==, != equality
= assignment

### Array elements

Array elements are accessed using the array subscript operator [ ]. For example:

diffuseColor += lightIntensity[3] * NdotL;


## Operators

Numbered in order of precedence. The relational and equality operators > < <= >= == != evaluate to a Boolean. To compare vectors component-wise, use functions such as lessThan(), equal(), etc.

Operator Description Associativity
1 () parenthetical grouping N/A
2 [] () . ++ -- array subscript function call & constructor structure field or method selector, swizzle postfix increment and decrement Left to Right
3 ++ -- + - ! prefix increment and decrement unary Right to Left
4 * / multiply and divide Left to Right
5 + - add and subtract Left to Right
7 < > <= >= relational Left to Right
8 == != equality/inequality Left to Right
12 && logical AND Left to Right
13 ^^ logical XOR Left to Right
14 || logical OR Left to Right
15 ?\: selection (one entire operand) Left to Right
16 = += -= *= /= assignment arithmetic assignment arithmetic assignment Left to Right
17 , sequence Left to Right

### Matrix and vector operations

When applied to scalar values, the arithmetic operators result in a scalar. For operators other than modulo, if one operand is a scalar and the other is a vector or matrix, the operation is performed componentwise and results in the same vector or matrix type. If both operations are vectors of the same size, the operation is performed componentwise (and returns the same vector type).

Operation Description
m = f * m Component-wise matrix multiplication by a scalar value
v = f * v Component-wise vector multiplication by a scalar value
v = v * v Component-wise vector multiplication by a vector value
m = m + m Matrix component-wise addition
m = m - m Matrix component-wise subtraction
m = m * m Linear algebraic multiply

If one operand is a vector matching the row or column size of our matrix, the multiplication operator can be used to do algebraic row and column multiplication.

Operation Description
m = v * m Row vector * matrix linear algebraic multiply
m = m * v Matrix * column vector linear algebraic multiply

Use the built-in functions for vector dot product, cross product, and component-wise multiplication:

Function Description
f = dot(v, v) Vector dot product
v = cross(v, v) Vector cross product
m = matrixCompMult(m, m) Component-wise multiply

## Program control

Function call Call by value-return
Iteration for (<init>;<test>;<next>)
{ break, continue }
Selection if ( ) { }
if ( ) { } else { }
switch () { break, case } - default case last
Jump break, continue, return
Entry half4 main(float2 fragCoord)

### For loop limitations

Similar to GLSL ES 1.0, 'for' loops are quite limited; the compiler must be able to unroll the loop. This means that the initializer, the test condition, and the next statement must use constants so that everything can be computed at compile time. The next statement is further limited to using ++, --, +=, or -=.

## Built-in functions

GT (generic type) is float, float2, float3, float4 or half, half2, half3, half4.

Most of these functions operate component-wise (the function is applied per-component). It's noted when that is not the case.

### Angle & trigonometric functions

Function parameters specified as an angle are assumed to be in units of radians. In no case will any of these functions result in a divide by zero error. If the divisor of a ratio is 0, then results will be undefined.

Function Description
GT radians(GT degrees) Converts degrees to radians
GT degrees(GT radians) Converts radians to degrees
GT sin(GT angle) Standard sine
GT cos(GT angle) Standard cosine
GT tan(GT angle) Standard tangent
GT asin(GT x) Returns an angle whose sine is x in the range of $\left[-{\pi\over 2},{\pi\over 2}\right]$
GT acos(GT x) Returns an angle whose cosine is x in the range of $\left[0,\pi\right]$
GT atan(GT y, GT x) Returns an angle whose trigonometric arctangent is $\left[{y\over x}\right]$ in the range of $\left[-\pi,\pi\right]$
GT atan(GT y_over_x) Returns an angle whose trigonometric arctangent is y_over_x in the range of $\left[-{\pi\over 2},{\pi\over 2}\right]$

### Exponential functions

Function Description
GT pow(GT x, GT y) Returns $x^y$
GT exp(GT x) Returns $e^x$
GT log(GT x) Returns $ln(x)$
GT exp2(GT x) Returns $2^x$
GT log2(GT x) Returns $log_2(x)$
GT sqrt(GT x) Returns $\sqrt{x}$
GT inversesqrt(GT x) Returns $1\over{\sqrt{x}}$

### Common functions

Function Description
GT abs(GT x) Absolute value
GT sign(GT x) Returns -1.0, 0.0, or 1.0 based on sign of x
GT floor(GT x) Nearest integer <= x
GT ceil(GT x) Nearest integer >= x
GT fract(GT x) Returns the fractional part of x
GT mod(GT x, GT y) Returns value of x modulo y
GT mod(GT x, float y) Returns value of x modulo y
GT min(GT x, GT y) Returns minimum value of x or y
GT min(GT x, float y) Returns minimum value of x or y
GT max(GT x, GT y) Returns maximum value of x or y
GT max(GT x, float y) Returns maximum value of x or y
GT clamp(GT x, GT minVal, GT maxVal) Returns x clamped between minVal and maxVal.
GT clamp(GT x, float minVal, float maxVal) Returns x clamped between minVal and maxVal
GT saturate(GT x) Returns x clamped between 0.0 and 1.0
GT mix(GT x, GT y GT a) Returns linear blend of x and y
GT mix(GT x, GT y, float a) Returns linear blend of x and y
GT step(GT edge, GT x) Returns 0.0 if x < edge, else 1.0
GT step(float edge, GT x) Returns 0.0 if x < edge, else 1.0
GT smoothstep(GT edge0, GT edge1, GT x) Performs Hermite interpolation between 0 and 1 when edge0 < x < edge1
GT smoothstep(float edge0, float edge1, GT x) Performs Hermite interpolation between 0 and 1 when edge0 < x < edge1

### Geometric functions

These functions operate on vectors as vectors, not component-wise. GT is float/half vectors in sizes 2-4.

Function Description
float/half length (GT x) Returns length of vector
float/half distance(GT p0, GT p1) Returns distance between points
float/half dot(GT x, GT y) Returns dot product
float3/half3 cross(float3/half3 x, float3/half3 y) Returns cross product
GT normalize(GT x) Normalize vector to length 1
GT faceforward(GT N, GT I, GT Nref) Returns N if dot(Nref, I) < 0, else -N.
GT reflect(GT I, GT N) Reflection direction I - 2 * dot(N,I) * N.
GT refract(GT I, GT N, float/half eta) Returns refraction vector

### Matrix functions

Type mat is any square matrix type.

Function Description
mat matrixCompMult(mat x, mat y) Multiply x by y component-wise
mat inverse(mat m) Returns the inverse of m

### Vector relational functions

Compare x and y component-wise. Sizes of input and return vectors for a particular call must match. T is the union of integer and floating point vector types. BV is a boolean vector that matches the size of the input vectors.

Function Description
BV lessThan(T x, T y) x < y
BV lessThanEqual(T x, T y) x <= y
BV greaterThan(T x, T y) x > y
BV greaterThanEqual(T x, T y) x >= y
BV equal(T x, T y) x == y
BV equal(BV x, BV y) x == y
BV notEqual(T x, T y) x != y
BV notEqual(BV x, BV y) x != y
bool any(BV x) true if any component of x is true
bool all(BV x) true if all components of x are true.
BV not(BV x) logical complement of x

### Color functions

Function Description
vec4 unpremul(vec4 color) Converts color value to non-premultiplied alpha
half3 toLinearSrgb(half3 color) Color space transformation to linear SRGB
half3 fromLinearSrgb(half3 color) Color space transformation

Sampler types aren't supported, but you can evaluate other shaders. If you need to sample a texture, you can create a BitmapShader object, and add it as a uniform. You can do this for any shader, which means you can directly evaluate any Android Shader without turning it into a Bitmap first, including other RuntimeShader objects. This allows for a huge amount of flexibility, but complex shaders can be expensive to evaluate, particularly in a loop.

uniform shader image;

image.eval(coord).a   // The alpha channel from the evaluated image shader
`

## Raw buffer sampling

Although most images contain colors that should be color-managed, some images contain data that isn’t actually colors, including images storing normals, material properties (e.g., roughness), heightmaps, or any other purely mathematical data that happens to be stored in an image. When using these kinds of images in AGSL, you can use a BitmapShader as a generic raw buffer using RuntimeShader#setInputBuffer. This will avoid color space transformations and filtering.

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Missing the information I need" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Too complicated / too many steps" },{ "type": "thumb-down", "id": "outOfDate", "label":"Out of date" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Samples / code issue" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }]
[{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]