Attributes
in_Colour
Syntax:
attribute vec4 in_Colour;
Returns:
vec4, vertex color and alpha
Description:
Vertex color and alpha. When applied to sprite this will be the image_blend and image_alpha, for most other draw_* functions it will be the
draw_set_color
and
draw_set_alpha
and for vertex buffers/primitives, the color you set for each vertex.

If you're using a custom vertex format that includes multiple colors, just use 'in_Colour0', 'in_Colour1', etc.
Example:
  • //Pass a varying 'v_vColor' to the fragment shader.
    v_vColour = in_Colour;
in_Position
Syntax:
attribute vec3 in_Position;
Returns:
vec3, vertex position
Description:
Vertex position in model-space. Most GML draw_* functions (e.g. draw_sprite) build their vertex buffer in world space so that they don't need the world matrix. Keep this in mind when you're using your own vertex buffer!
Example:
  • //Output the projection-space vertex position.
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position,1.);
in_TextureCoord
Syntax:
attribute vec2 in_TextureCoord;
Returns:
vec2, texture coordinates
Description:
The texture coordinates (or uvs) range from 0 to 1 across the texture page. That means that surfaces and sprites that are on their own texture page will have normalized uvs, which can be very useful. However for other sprites you can always pass in the sprite uvs (from
sprite_get_uvs
) and normalize them yourself.

In GM, you're encouraged to use texture coordinates for any extra attributes (e.g, tangents, bone weights, etc) so any other attribute name will be interpreted as a 'texture coordinate' attribute (e.g in_Tangent, in_Bitangent, etc will work fine).
Example:
  • //Pass a varying 'v_vTexcoord' to the fragment shader.
    v_vTexcoord = in_Texcoord;
in_Normal
Syntax:
attribute vec3 in_Normal;
Returns:
vec3, vertex normal
Description:
Vertex geometry normal. This is only used in some custom vertex formats, with 3D models that need geometry normals (usually for lighting). A normal is a vector perpendicular to the model's surface. Make sure the normal vectors have a length of 1.0.
Example:
  • //Compute diffuse lighting using a light direction vector
    float diffuse = max(dot(in_Normal, light_dir), 0.0);
Functions
texture2D(texture, coordinates, [bias])
Syntax:
texture2D(sampler2D, vec2, [float])
Arguments:
  • texture
    Description:
    ID of the texture to sample.
  • coordinates
    Description:
    x and y texture coordinates of the pixel to sample.
  • bias
    Description:
    Optional mipmap bias.
Returns:
vec4, texel color and alpha
Description:
Samples the texture at the given texture coordinates for color and alpha. Texture coordinates are between 0 to 1 and they represent a pixel position on the sampler's texture page. Each texture (or sprite) has its own set of texture coordinates within the texture page, so sometimes you may need to convert from one set of coordinates to another. You can use the GML
sprite_get_uvs
to get the set of coordinates, which can be passed into the shader via uniforms. Surfaces or sprites with the 'Separate Texture Page' box ticked will always have a range of 0 to 1 so they are easier to deal with.
Also, the sampled pixel will be filtered by GM (no interpolation, linear interpolation or mipmapping) which is why we call this a 'texel'.
With mipmapping enabled, you can add a bias to the LOD level (this does not work with surfaces!). Using a positive bias will reduce the resolution to give it a softer look and a negative bias will make higher resolution if possible.
Examples:
  • texture2D(gm_BaseTexture, v_vTexcoord);
  • //Using the sampler 'uni_diffuse' and 1.0 bias (half resolution with mipmapping).
    texture2D(uni_diffuse, v_vTexcoord, 1.0);
texture2DLod(texture, coordinates, lod)
Syntax:
texture2DLod(sampler2D, vec2, float)
Arguments:
  • texture
    Description:
    ID of the texture to sample.
  • coordinates
    Description:
    x and y texture coordinates of the pixel to sample.
  • lod
    Description:
    Overwrites mipmap LOD.
Returns:
vec4, texel color and alpha
Description:
Currently not supported in GM!

Samples the texture at the given texture coordinates for color and alpha. Texture coordinates are between 0 to 1 and they represent a pixel position on the sampler's texture page. Each texture (or sprite) has its own set of texture coordinates within the texture page, so sometimes you may need to convert from one set of coordinates to another. You can use the GML
sprite_get_uvs
to get the set of coordinates, which can be passed into the shader via uniforms. Surfaces or sprites with the 'Separate Texture Page' box ticked will always have a range of 0 to 1 so they are easier to deal with.
It's worth noting that the sampled pixel will be filtered by GM (no interpolation, linear interpolation or mipmapping, etc) which is why we call this a 'texel'.
This works like texture2D' except it overwrites the automatic LOD level with the LOD you specify. If mipmapping is disabled, it will output the same result as texture2D would.
Example:
  • //Force half resolution with mipmapping.
    texture2DLod(gm_BaseTexture, v_vTexcoord, 1.0);
texture2DProj(texture, coordinates, [bias])
Syntax:
texture2DProj(sampler2D, vec3/vec4, [float])
Arguments:
  • texture
    Description:
    ID of the texture to sample.
  • coordinates
    Description:
    x, y and z for projecting texture coordinates.
  • bias
    Description:
    Optional mipmap bias.
Returns:
vec4, texel color and alpha
Description:
texture2DProj is like texture2D' except it computes it's texture coordinates from the x and y coordinates divided by the last component (z component for a vec3 or w for a vec4); Useful in 3D when you need to project a 2D texture onto 3D geometry. Then it samples the texture at the given texture coordinates for color and alpha. Texture coordinates are between 0 to 1 and they represent a pixel position on the sampler's texture page. Each texture (or sprite) has its own set of texture coordinates within the texture page, so sometimes you may need to convert from one set of coordinates to another. You can use the GML
sprite_get_uvs
to get the set of coordinates, which can be passed into the shader via uniforms. Surfaces or sprites with the 'Separate Texture Page' box ticked will always have a range of 0 to 1, so they are easier to deal with.
Also, the sampled pixel will be filtered by GM (no interpolation, linear interpolation or mipmapping) which is why we call this a 'texel'.
With mipmapping, you can add a bias to the LOD level (this does not work with surfaces!). Using a positive bias will reduce the resolution to give it a softer look and a negative bias will make higher resolution if possible.
Example:
  • //Project a texture using frag coordinates.
    texture2DProj(gm_BaseTexture, gl_FragCoord.xyz);
texture2DProjLod(texture, coordinates, lod)
Syntax:
texture2DProjLod(sampler2D, vec3/vec4, float)
Arguments:
  • texture
    Description:
    ID of the texture to sample.
  • coordinates
    Description:
    x, y and z for projecting texture coordinates.
  • lod
    Description:
    Overwrites mipmap LOD.
Returns:
vec4, texel color and alpha
Description:
Currently not supported in GM!

texture2DProjLod is like texture2DLod except it computes it's texture coordinates from the x and y coordinates divided by the last component (z component for a vec3 or w for a vec4); Useful in 3D when you need to project a 2D texture onto 3D geometry. Then it samples the texture at the given texture coordinates for color and alpha. Texture coordinates are between 0 to 1 and they represent a pixel position on the sampler's texture page. Each texture (or sprite) has its own set of texture coordinates within the texture page, so sometimes you may need to convert from one set of coordinates to another. You can use the GML
sprite_get_uvs
to get the set of coordinates, which can be passed into the shader via uniforms. Surfaces or sprites with the 'Separate Texture Page' box ticked will always have a range of 0 to 1, so they are easier to deal with.
Also, the sampled pixel will be filtered by GM (no interpolation, linear interpolation or mipmapping) which is why we call this a 'texel'.
With mipmapping, it overwrites the automatic LOD level with the specific LOD you want. If mipmapping is disabled, it will output the same result as texture2DProj would.
Example:
  • //Project a texture at half resolution (using mipmapping).
    texture2DProjLod(gm_BaseTexture, gl_FragCoord.xyz, 1.0);
floor(x)
Syntax:
floor(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, x rounded down
Description:
floor
is like in GML, it returns 'x' rounded down to the nearest whole number. So
floor(1.5)
returns 1.0
Example:
  • float two = floor(2.5);
ceil(x)
Syntax:
ceil(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, x rounded up
Description:
ceil
is like in GML, it returns 'x' rounded up to the nearest whole number. So
ceil(1.5)
returns 2.0
Example:
  • float three = ceil(2.5);
fract(x)
Syntax:
fract(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, fractional part of x
Description:
fract
is similar to
frac
in GML with the same results for positive
x
(not with negatives). This returns just the fractional part of 'x', removing the whole number part. Internally, it's computed as
x - floor(x)
, so
fract(3.14)
returns 0.14.

Note: the GML function relates with the shader function like so:
frac(x) = fract(abs(x)) * sign(x)
Example:
  • float half = fract(2.5);
mod(x, y)
Syntax:
mod(float/vec, float/vec)
Arguments:
  • x
    Description:
    The input value.
  • y
    Description:
    The divisor.
Returns:
float/vec, fractional part of x
Description:
mod
is similar to the GML modulo operator (also called
mod
), giving the same results for positive
x
(not with negatives). This returns the remainder of
x
divided by
y
which is computed as
x - floor(x/y)*y
.

Note: the GML operator relates with the shader function like so:
x mod y = mod(abs(x),y) * sign(x)
Example:
  • float two = mod(7.0,5.0);
sign(x)
Syntax:
sign(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, sign of x
Description:
sign
is like in GML, it returns the sign for each component of
x
. So if x is positive, it returns 1.0, if x is negative it returns -1.0 and 0.0 if x equals zero.
Example:
  • float one = sign(10.);
abs(x)
Syntax:
abs(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, x as a positive
Description:
abs
is like in GML, it returns 'x' as a positive number. So if 'x' is negative 'abs' returns '-x' so the result is always positive (or 0).
Example:
  • float five = abs(-5.0);
min(x, y)
Syntax:
min(float/vec, float/vec)
Arguments:
  • x
    Description:
    The first input value.
  • y
    Description:
    The second input value.
Returns:
float/vec, the lesser of x and y
Description:
min
is like in GML (except limited to 2 input arguments), returns the lesser of the two values. So it will return 'x' if 'x' is less than 'y' and otherwise it returns 'y'.
Example:
  • float one = min(1.0, 4.0);
max(x, y)
Syntax:
max(float/vec, float/vec)
Arguments:
  • x
    Description:
    The first input value.
  • y
    Description:
    The second input value.
Returns:
float/vec, the greater of x and y
Description:
max
is like in GML (except limited to 2 input arguments), returns the greater of the two values. So it will return 'x' if 'x' is greater than 'y' and otherwise it returns 'y'.
Example:
  • float four = max(1.0, 4.0);
clamp(x, min, max)
Syntax:
clamp(float/vec, float/vec, float/vec)
Arguments:
  • x
    Description:
    The input value.
  • min
    Description:
    The minimum value.
  • max
    Description:
    The maximum value.
Returns:
float/vec, x between min and max
Description:
clamp
is just like in GML, returning 'x' if 'x' is between 'min' and 'max'. If 'x' is less than 'min' it returns 'min' and if 'x' is greater than 'max' it returns 'max', effectively clamp 'x' to the 'min-max' range.
Example:
  • float five = abs(-5.0);
mix(x1, x2, amt)
Syntax:
mix(float/vec, float/vec, float/vec)
Arguments:
  • x1
    Description:
    The first (or source) value.
  • x2
    Description:
    The second (or destination) value.
  • amt
    Description:
    The amount to intepolate.
Returns:
float/vec, mixture of a and b
Description:
mix is like the GML
lerp
, it linearly interpolates between 'x1' and 'x2' by the amount 'amt'. So
mix(x1,x2,0.0)
would equal 'x1' and
mix(x1,x2,1.0)
equals 'x2'. When 'amt' is anything between 0 and 1, the result will be somewhere between x1 and x2.
Mix is computed as:
x1 + (x2-x1)*amt
so 'x1' and 'x2' must have the same number of components however 'amt' can be a float or a vector.
Examples:
  • //Mix between the source color and destination color, by 'factor' (float or vec3)
    vec3 col = mix(src, dst, factor);
  • //Get the source's red and green channels and the destination's blue channel.
    vec3 col = mix(src, dst, vec3(0,0,1));
step(edge, x)
Syntax:
step(float/vec, float/vec)
Arguments:
  • edge
    Description:
    The edge value for comparing.
  • x
    Description:
    The input value.
Returns:
float/vec, zero or one
Description:
Returns 0.0 when 'x' is less than 'edge' and 1.0 when it is not. This sometimes can be used as a substitute for an if statement.
Example:
  • //Set the alpha to 0.0 if 'color.a' is less-than 0.5:
    color.a = step(0.5, color.a);
smoothstep(edge0, edge1, x)
Syntax:
smoothstep(float/vec, float/vec, float/vec)
Arguments:
  • edge0
    Description:
    The starting edge.
  • edge1
    Description:
    The ending edge.
  • x
    Description:
    The input value.
Returns:
float/vec, between zero and one
Description:
Returns 0.0 if 'x' is equal to 'edge0' and 1.0 if 'x' is equal to 'edge1'. Any value of 'x' in between will be smoothly blended between zero and one, making it quite useful for gradients.
If you want to take a value from any range and gaurantee a result between 0 and 1, this is probably what you're looking for. You can then add/multiply as necessary to map it to any other range.

Note: This gradient is not linear, but rather it tapers off at both ends. If you're curious, here's how it is computed internally:
float range = (x-edge0)/(edge1-edge0); //Map to 0-1 range

float y = clamp(range, 0.0, 1.0); //Clamp to 0-1

return 3.0*y*y - 2.0*y*y*y; //Return smooth, cubic value
Examples:
  • //Set the light brightness to 1.0 at the center and fade out to 'radius'
    float light = smoothstep(radius, 0.0, dist);
  • //Increase the color contrast by using a narrower range.
    color = smoothstep(contrast, 1.0-contrast, color);
pow(x, y)
Syntax:
pow(float/vec, float/vec)
Arguments:
  • x
    Description:
    The base.
  • y
    Description:
    The exponent.
Returns:
float/vec, 'x' to the 'y' power
Description:
Returns x raised to the y power, so
pow(2.0,3.0) = 2.0*2.0*2.0
or 8. Make sure your arguments have the same number of dimensions. Raising a vec3 to a float power will cause an error! Also make sure 'x' is not a negative number or it may cause artifacts (typically a black screen).
Examples:
  • //Adjust for gamma correction.
    vec3 gamma_encode = pow(color.rgb, vec3(2.2));
  • //Make a cool blue gradient using different exponents.
    vec3 gradient = pow(uv.yyy, vec3(2.0, 1.0, 0.5))
sqrt(x)
Syntax:
sqrt(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, square root of x
Description:
Returns the square root of x, just like in GML. Make sure 'x' is not a negative number or it will cause artifacts (typically a black screen).
Example:
  • //Compute sphere heightat the current position, 'pos'.
    float sphere_height = sqrt(radius * radius - dot(pos, pos));
inversesqrt(x)
Syntax:
inversesqrt(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, one over the square root of x
Description:
Returns the reciprocal of the square root of x (
1.0 / sqrt(x)
). Shaders are relatively efficient at computing this so it's better than dividing by sqrt. Make sure 'x' is greater than 0.0 as a value of 0.0 will cause a division-by-zero error.
Example:
  • //Compute a weight value from an inverse square-root.
    float weight = inversesqrt(i+1.0);
exp(x)
Syntax:
exp(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, 'e' to the 'x' power
Description:
Returns Euler's number, 'e' raised to the 'x' power. e has a value of
2.7182818...
, which is the exponentation standard because of it's unique properties.
This is faster to compute than pow to compute because it deals with a fixed base.
It's also the inverse function of log, meaning
log(exp(x)) == x
Example:
  • //This compute lighting with an exponentially falloff.
    float light = exp(-dist * falloff);
exp2(x)
Syntax:
exp2(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, 2 to the 'x' power
Description:
Returns 2.0 raised to the 'x' power. So
exp2(1.0) = 2.0
,
exp2(2.0) = 4.0
and
exp2(8.0) = 256.0
.
This is faster to compute than pow to compute because it deals with a fixed base.
It's also the inverse function of log2, meaning
log2(exp2(x)) == x
Example:
  • //This compute lighting with an exponentially falloff.
    float light = exp(-dist * falloff);
log(x)
Syntax:
log(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, base 'e' log of 'x'
Description:
Returns the Natural logarithm. In short, this is the inverse function of exp, meaning
log(exp(x)) == x
.
Example:
  • //Smooth maximum based off iq's smin function: https://iquilezles.org/www/articles/smin/smin.htm
    float smax = log(exp(a*k)+exp(b*k))/k;
log2(x)
Syntax:
log2(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, base 2 log of 'x'
Description:
Returns the Binary logarithm. In short, this is the inverse function of exp2, meaning
log2(exp2(x)) == x
.
Example:
  • //Round x up to a power of 2 number (e.g. 2,4,8...)
    float powerOf2 = exp2(ceil(log2(x)));
length(x)
Syntax:
length(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float, length of vector
Description:
Returns the length of a vector by calculating it's hypotenuse. It works on any number of dimensions with the float variant behaving like
abs(x)

This also can be calculated as
sqrt(dot(x,x))
so be sure to use dot instead if you need the distance squared.
Example:
  • //Calculate a light's attenuation based the distance to the light
    float light = max(1.0 - length(pixel_pos - light_pos) / radius, 0.0);
distance(a, b)
Syntax:
distance(float/vec, float/vec)
Arguments:
  • a
    Description:
    The starting point.
  • b
    Description:
    The end point.
Returns:
float, distance between points
Description:
Returns the distance between two vectors by calculating it's hypotenuse. It works on any number of dimensions with the float variant behaving like
abs(a - b)

This also can be calculated as
sqrt(dot(a - b, a - b))
so be sure to use dot instead if you need the distance squared.
Example:
  • //Calculate a light's attenuation based the distance to the light
    float light = max(1.0 - distance(pixel_pos, light_pos) / radius, 0.0);
normalize(x)
Syntax:
normalize(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, 'x' with a length of 1.0
Description:
Returns the vector, divided by it's length, giving it a length of 1.0. In the rare event where the vector has a length of 0.0, it will return all zeros.
This is often used for lighting, need to know the direction without the magnitude.
Example:
  • //Compute the dot lighting with the light direction
    float light_dot = max(dot(normal, normalize(pos - light_pos)), 0.0);
dot(a, b)
Syntax:
dot(float/vec, float/vec)
Arguments:
  • a
    Description:
    The first vector.
  • b
    Description:
    The second vector.
Returns:
float, dot product of 'a' and 'b'
Description:
Returns the sum of the components of
a * b
. So if 'a' and 'b' are vec2s then
dot(a, b) = a.x * b.x + a.y * b.y
.
Dot products have many different uses. If you know both vectors are normalized, then the dot product will be 1.0 if they are pointed in the same direction, 0.0 if perpendicular and -1.0 if opposite along with values in between. You can use acos on the dot product to find the angle between the two vectors.
If one vector is normalized, the dot product tells you how far a vector is along that direction.
Examples:
  • //Compute the luminance using a weighted average
    float grayscale = dot(color.rgb, vec3(0.299, 0.587, 0.114));
  • //A gradient between a start and end point
    vec2 direction = end - start;
    float gradient = dot(position - start, direction) / dot(direction, direction);
  • //Compute the dot lighting with the light direction
    float light_dot = max(dot(normal, normalize(pos - light_pos)), 0.0);
  • //Compute a pseudo-random hash from 'n'
    float hash = fract(sin(dot(n, vec2(4.044,6.536))) * 4101.);
cross(a, b)
Syntax:
cross(vec3, vec3)
Arguments:
  • a
    Description:
    The first vector.
  • b
    Description:
    The second vector.
Returns:
vec3, cross product of 'a' and 'b'
Description:
Computes the cross product 'a' and 'b' which is always perpendicular to both vectors. If 'a' and 'b' are parallel or opposite or either one is zero, the result will be vec3(0.0). The formula for calculating a cross product is
cross(a, b) = a.yzx * b.zxy - a.zxy * b.yzx
.
Examples:
  • //Compute the side vector from the camera forward and up
    vec3 side = normalize(cross(forward, up));
  • //Compute the normal from standard derivatives
    vec3 normal = normalize(cross(dFdx(pos), dFdy(pos)));
reflect(i, n)
Syntax:
reflect(float/vec, float/vec)
Arguments:
  • i
    Description:
    The incident vector.
  • n
    Description:
    The normal vector.
Returns:
float/vec, reflection of 'i' against 'n'
Description:
Reflects the incidence ('i') vector off of the normal ('n'). You probably want both vectors normalized, otherwise you'll get a non-normalized result. The formula for calculating this reflection is
i - 2.0 * dot(n, i) * n
.
Example:
  • //Compute the reflection of the viewspace direction and the normal
    vec3 reflection_direction = reflect(normalize(view), normal);
refract(i, n, r)
Syntax:
refract(float/vec, float/vec, float)
Arguments:
  • i
    Description:
    The incident vector.
  • n
    Description:
    The normal vector.
  • r
    Description:
    The ratio between refraction indices.
Returns:
float/vec, refraction ray
Description:
Used to compute the direction of a refracted ray using the angle of incidence ('i'), the normal ('n') and the ratio between the refraction indices. So for example, water has a refractive index of about 1.33 and air is 1.0 so refracting into water would have a ratio of
1.0 / 1.33
and refracting out would be
1.33 / 1.0
.

Note: Make sure both vectors are normalized or the forumla won't work correctly. If you're curious about the forumla, here it is:
float k = 1.0 - r * r * (1.0 - dot(n, i) * dot(n, i));

(k < 0.0) ? i-i : r * i - (r * dot(n, i) + sqrt(k)) * n;
Example:
  • //Compute the refraction vector into water
    vec3 refraction_direction = refract(normalize(view), normal, 1.0/1.33);
faceforward(d, i, r)
Syntax:
faceforward(float/vec, float/vec, float/vec)
Arguments:
  • d
    Description:
    The input vector.
  • i
    Description:
    The incident vector.
  • r
    Description:
    The reference vector.
Returns:
float/vec, 'd' oriented by 'i' and 'r'
Description:
This flips the value of 'd' depending on if 'i' is facing away from 'r' and does not flip if they're facing the same direction. If I'm being honest, I barely have a use for this.

Internally, this computed like so:
faceforward(d,i,r) = dot(i, r) < 0.0 ? d : -d;
Example:
  • //Flip a random kernel if it's facing against the normal
    vec3 hemisphere = faceforward(kernel, kernel, normal)
matrixCompMult(a, b)
Syntax:
matrixCompMult(mat, mat)
Arguments:
  • a
    Description:
    The first matrix.
  • b
    Description:
    The second matrix.
Returns:
mat, component product of 'a' and 'b'
Description:
This multiplies matrices, 'a' and 'b', component by component and returns the result. So
a[0,0] * b[0,0]
,
a[1,0] * b[1,0]
and so on. Make sure the matrices have the same dimensions or you'll get an error!
Example:
  • //Compute weights as a component product of 'a' and 'b'
    mat4 weights = matrixCompMult(a, b);
radians(x)
Syntax:
radians(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, convert 'x' to radians
Description:
Converts 'x' degrees into radians. Degrees range from 0 to 360 and radians range from 0 to 6.2831853. All the Trigonometry functions, like sin use radians so you may need to use this.

Internally, this computed like so:
radians(x) = x / 180.0 * 3.1415926;
Example:
  • //Convert 60 degree to radians
    float sixty = radians(60.0);
    //Compute a rotation matrix for this angle
    mat2 rotate = mat2(cos(sixty), sin(sixty), -sin(sixty), cos(sixty));
degrees(x)
Syntax:
degrees(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, convert 'x' to degrees
Description:
Converts 'x' radians into degrees. Degrees range from 0 to 360 and radians range from 0 to 6.2831853. All the Trigonometry functions, like sin use radians so you'll probably need to convert back to radians.

Internally, this computed like so:
degrees(x) = x / 3.1415926 * 180.0;
Example:
  • //Convert pi/2 to degrees (about 90)
    float ninety = degrees(1.5707963);
sin(x)
Syntax:
sin(float/vec)
Arguments:
  • x
    Description:
    The input angle (radians).
Returns:
float/vec, the sine of 'x'
Description:
Computes the sine of 'x'. It's mostly used to tell you the y-position of a point along a circle's edge at angle 'x' (in radians). Here's an illustration. It ranges between -1.0 and 1.0 so you can multiply it by the circle's radius to recreate something like 'lengthdir_y' in GML.
Examples:
  • //Compute the direction vector from a radian angle
    vec2 direction = vec2(cos(angle), sin(angle));
  • //Compute a pseudo-random hash from 'n'
    float hash = fract(sin(dot(n, vec2(4.044,6.536))) * 4101.);
cos(x)
Syntax:
cos(float/vec)
Arguments:
  • x
    Description:
    The input angle (radians).
Returns:
float/vec, the cosine of 'x'
Description:
Computes the cosine of 'x'. It's mostly used to tell you the x-position of a point along a circle's edge at angle 'x' (in radians). Here's an illustration. It ranges between -1.0 and 1.0 so you can multiply it by the circle's radius to recreate something like 'lengthdir_x' in GML.
Example:
  • //Compute the direction vector from a radian angle
    vec2 direction = vec2(cos(angle), sin(angle));
tan(x)
Syntax:
tan(float/vec)
Arguments:
  • x
    Description:
    The input angle (radians).
Returns:
float/vec, the tangent of 'x'
Description:
Computes the tangent of 'x'. It's used to tell you the ratio of y/x-position of a point along a circle's edge at angle 'x' (in radians). In otherwords it's the same as
tan(x) = sin(x) / cos(x)
. It ranges from negative infinity to positive infinity.
Example:
  • //Compute the y/x ratio at 'angle'
    float ratio = tan(angle);
asin(x)
Syntax:
asin(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, arcsin of 'x'
Description:
Computes the arcsin of 'x'. It's the inverse function of sin which means that
asin(sin(x)) = x;
. Just make sure that 'x' is -1.0, 1.0 or something in between as all other values are return 0.0.
asin(x) will only return a value between -pi/2 and pi/2.
Example:
  • //Compute angle 'a' for y = sin(a)
    float angle = asin(y);
acos(x)
Syntax:
acos(float/vec)
Arguments:
  • x
    Description:
    The input value.
Returns:
float/vec, arccos of 'x'
Description:
Computes the arccos of 'x'. It's the inverse function of cos which means that
acos(cos(x)) = x;
. Just make sure that 'x' is -1.0, 1.0 or something in between as all other values are return 0.0.
acos(x) will only return a value between 0 and pi.
Example:
  • //Compute angle 'a' for x = cos(a)
    float angle = acos(x);
atan(y, [x])
Syntax:
atan(float/vec, [float/vec])
Arguments:
  • y
    Description:
    The ratio of y to x, or just y if using both arguments.
  • x
    Description:
    The optional x argument.
Returns:
float/vec, arctan of 'y'
Description:
Computes the arctan of 'y'. It's helpful to think of
atan
as the GLSL equivalent of
point_direction
in GML, so it can be used to find the angle between two points (in radiansradians) like so:
atan(y2-y1, x2-x1)
.
It's also approximately the inverse function of tan which means that
atan(tan(y)) = y;
. 'y' can any value between negative infinity and positive infinity.
atan(y) will only return a value between -pi/2 and pi/2 while atan(y,x) will return a value between -pi and pi.
Examples:
  • //Compute angle for the y to x ratio
    float angle = atan(y/x);
  • //Compute angle between p1 and p2
    float angle2 = atan(p2.y-p1.y, p2.x-p1.x);
equal(a, b)
Syntax:
equal(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' equals 'b'
Description:
Returns true if 'a' is equal to 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true for each axis that equals 0.0
    bvec3 origin = equal(position, vec3(0.0, 0.0, 0.0));
notEqual(a, b)
Syntax:
notEqual(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' == 'b'
Description:
Returns true if 'a' is NOT equal to 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true for each axis that does not equal 0.0
    bvec3 origin = notEqual(position, vec3(0.0, 0.0, 0.0));
lessThan(a, b)
Syntax:
lessThan(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' < 'b'
Description:
Returns true if 'a' is less than 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true for each axis that is less than 0.0
    bvec3 negative = lessThan(position, vec3(0.0, 0.0, 0.0));
lessThanEqual(a, b)
Syntax:
lessThanEqual(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' <= 'b'
Description:
Returns true if 'a' is less than or equal to 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true if both axis of position are within 10.0 units of 0, 0
    bool box = all(lessThanEqual(abs(position.xy), vec2(10.0)));
greaterThan(a, b)
Syntax:
greaterThan(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' > 'b'
Description:
Returns true if 'a' is greater than 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true for each axis that is greater than 0.0
    bvec3 positive = greaterThan(position, vec3(0.0, 0.0, 0.0));
greaterThanEqual(a, b)
Syntax:
greaterThanEqual(float/int/vec, float/int/vec)
Arguments:
  • a
    Description:
    The first input value.
  • b
    Description:
    The second input value.
Returns:
bool/bvec, component-wise 'a' >= 'b'
Description:
Returns true if 'a' is greater than or equal to 'b'. With vectors it compares each component separately, returning a bvec.
Example:
  • //Returns true if any axis is 10.0 units or more units away from of 0, 0
    bool outside = any(greaterThanEqual(abs(position.xy), vec2(10.0)));
any(x)
Syntax:
any(bvec)
Arguments:
  • x
    Description:
    The boolean input value.
Returns:
bool, true if any component is true
Description:
Returns true if at least one component of 'x' is true.

Does not work on bools. It must be used on boolean vectors.
Example:
  • //Returns true if any axis is 10.0 units or more units away from of 0, 0
    bool outside = any(greaterThanEqual(abs(position.xy), vec2(10.0)));
all(x)
Syntax:
all(bvec)
Arguments:
  • x
    Description:
    The boolean input value.
Returns:
bool, true if all components are true
Description:
Returns true only when all components of 'x' are true.

Does not work on bools. It must be used on boolean vectors.
Example:
  • //Returns true if both axis of position are within 10.0 units of 0, 0
    bool box = all(lessThanEqual(abs(position.xy), vec2(10.0)));
not(x)
Syntax:
not(bvec)
Arguments:
  • x
    Description:
    The boolean input value.
Returns:
bvec, component-wise not operator
Description:
Returns the inverse of 'x', so true components become false and false becomes true.

Does not work on bools. It must be used on boolean vectors.
Example:
  • //Another way to do notEqual(a, b) in GLSL ES
    bvec3 not_equal = not(equal(a, b));
Built-in Variables
gl_Position
Description:
This variable is required in the vertex shader to set vertex position. So with this you have direct control of each vertex's position (useful for effects like shockwaves or water).
The make sure to set the value in projection-space.

Note: This is a vec4. The w-component is used for all the matrix translations. When in doubt, leave it as 1.0!
Example:
  • //Output the projection-space vertex position
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
gl_FragColor
Description:
This is a required vec4 in the fragment shader to sets the pixel's output color and alpha. You should only set this once.

Note: you can use gl_FragData instead of gl_FragColor.
Examples:
  • //Output solid white
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
  • //Output the base-texture
    gl_FragColor = texture2D(gm_BaseTexture, v_vTexcoord);
gl_FragData[]
Description:
This is a vec4 array that can be used in the fragment shader to set the pixel's output color and alpha (as a RGBA vec4) instead of gl_FragColor. This is meant to be used for MRTs with
surface_set_target_ext
however some platforms only support one output. Check out gl_MaxDrawBuffers for the number of supported render targets.
Examples:
  • //Output solid white
    gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
  • //Output the base-texture
    gl_FragData[0] = texture2D(gm_BaseTexture, v_vTexcoord);
gl_MaxDrawBuffers
Description:
This is an int for the number of supported MRTs on the current platform (e.g. Windows may support 4, while an Android device supports only 1).
Example:
  • //If supported, output solid white on the second render target
    if (gl_MaxDrawBuffers>1) gl_FragData[1] = vec4(1.0);
gl_FragCoord
Description:
This is a read-only vec4 in the fragment shader that contains the fragment/pixel position in the window (relative to the top-left corner). The z-component will always be 0.0 and the w-component is always 1.0
Example:
  • //Get the current 2D pixel position in the window.
    vec2 pixel = gl_FragCoord.xy;
gl_FrontFacing
Description:
This is a read-only bool in fragment shader indicating whether or not a triangle is front-facing (true) or back-facing (false).

Note: If your models are wound clockwise instead of counter-clockwise, you will want to negate the value. This is only useful if you have face culling off so that you can see both sides of a triangle.
Example:
  • //Set the front facing triangles to solid white
    if (gl_FrontFacing) gl_FragColor = vec4(1.0);
gm_Matrices[]
Description:
gm_Matrices is an array of matrices with five to choose from:
  • MATRIX_VIEW: Used to orient space with the view. So the x-axis is always left/right on the screen, the y-axis is up and down and positive z is forward. This is often used for fog because you can get the distance relative to the camera. It's also used for screenspace effects such SSAO.
  • MATRIX_PROJECTION: This matrix accounts for aspect ratio, Field Of View and the near/far clipping planes
  • MATRIX_WORLD: This is an extra matrix, intended for any transformations you might need, like scaling, rotating and translating.
  • MATRIX_WORLD_VIEW: Combines world matrix transformations with the view position and orientation.
  • MATRIX_WORLD_VIEW_PROJECTION: Combines world matrix transformations with the view position/orientation and projection perspective.
Examples:
  • //Get the world-space position
    vec3 world = (gm_Matrices[MATRIX_WORLD] * vec4(in_Position, 1.0)).xyz;
  • //Output the projection-space vertex position
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
gm_BaseTexture
Description:
This is the sampler from whatever you're drawing. For example, if you're drawing a sprite, it will give you the sprite's texture page. It's sometimes useful to put a sprite on a separate texture page. If you need an additional texture, you can always add a uniform sampler2D!
Example:
  • //Sample the base-texture
    vec4 tex = texture2D(gm_BaseTexture, v_vTexcoord);
gm_FogStart
Description:
This is a float for vertex shader containing the fog start distance from
gpu_set_fog()
. This can be used with gm_RcpFogRange to compute the fog at the current position.
Example:
  • //Calculate the fog amount from the view_space depth
    float fog_factor = (view_pos.z - gm_FogStart) * gm_RcpFogRange;
gm_RcpFogRange
Description:
This is a float for vertex shader containing the reciprocal of the fog range value from
gpu_set_fog()
, computed as
1.0 / (fog_end - fog_start)
. This can be used with gm_FogStart to compute the fog at the current position.
Example:
  • //Calculate the fog amount from the view_space depth
    float fog_factor = (view_pos.z - gm_FogStart) * gm_RcpFogRange;
gm_VS_FogEnabled
Description:
This is a bool for vertex shader telling if the
gpu_set_fog()
is enabled. There's a separate bool called gm_PS_FogEnabled for the fragment shader.
Example:
  • //Checking if the fog (vertex) is enabled
    if (gm_VS_FogEnabled)
gm_PS_FogEnabled
Description:
This is a bool for fragment shader telling if the
gpu_set_fog()
is enabled. There's a separate bool called gm_VS_FogEnabled for the vertex shader.
Example:
  • //Checking if the fog (fragment) is enabled
    if (gm_PS_FogEnabled)
gm_FogColour
Description:
This is a vec4 for fragment shader containing the fog color from
gpu_set_fog()
. The alpha channel is always 1.0.
Example:
  • //Blend from the texture color to the fog color based on 'fog_factor'
    gl_FragColor = mix(tex_color, gm_FogColour, fog_factor);
gm_LightingEnabled
Description:
This is a bool for vertex shader to check if GM's lighting system is enabled set with
draw_set_lighting()
.
Example:
  • //Check if the lighting is enabled before
    if (gm_LightingEnabled)
gm_AmbientColour
Description:
This is a vec4 for vertex shader to containing the ambient light color from
draw_light_define_ambient()
. The alpha-component will always be 1.0.
Example:
  • //Initialize 'lighting' with the ambient light color
    vec4 lighting = gm_AmbientColour;
gm_Lights_Direction[]
Description:
This is a vec4 array for vertex shader to containing the light direction vector set from
draw_light_define_direction()
. The w-component is 1.0 if the light is enabled and 0.0 if not. xyz components will always be normalized.
This array's size is set by a macro called
MAX_VS_LIGHTS
which is hardcoded to 8, so you're limited to 8 lights.
Example:
  • //Add directional lights to 'lighting'
    lighting += DoDirLight(world_normal, gm_Lights_Direction[i], gm_Lights_Colour[i]);
gm_Lights_PosRange[]
Description:
This is a vec4 array for vertex shader to containing the light position and range set from
draw_light_define_point()
. The w-component is the light's range (0.0 if disabled).
This array's size is set by a macro called
MAX_VS_LIGHTS
which is hardcoded to 8, so you're limited to 8 lights.
Example:
  • //Add point lights to 'lighting'
    lighting += DoPointLight(world_pos, world_normal, gm_Lights_PosRange[i], gm_Lights_Colour[i]);
gm_Lights_Colour[]
Description:
This is a vec4 array for vertex shader to containing the light color
draw_light_define_point()
or
draw_light_define_direction()
. The alpha-component will always be 1.0.
This array's size is set by a macro called
MAX_VS_LIGHTS
which is hardcoded to 8, so you're limited to 8 lights.
Example:
  • //Add point lights to 'lighting'
    lighting += DoPointLight(world_pos, world_normal, gm_Lights_PosRange[i], gm_Lights_Colour[i]);
gm_AlphaTestEnabled
Description:
This is a bool for fragment shader telling if alpha testing from
gpu_set_alphatestenable()
is enabled. You can also get the alpha test reference from gm_AlphaRefValue.
Example:
  • //If alpha testing is enabled, discard alpha values below the reference value
    if (gm_AlphaTestEnabled && alpha < gm_AlphaRefValue) discard;
gm_AlphaRefValue
Description:
This is a float for fragment shader containing the alpha test reference from
gpu_set_alphatestref()
. You can also get the alpha test toggle from gm_AlphaTestEnabled.
Example:
  • //If alpha testing is enabled, discard alpha values below the reference value
    if (gm_AlphaTestEnabled && alpha < gm_AlphaRefValue) discard;