Skip to content

Shader built-ins

These work the same in an interpreted and in a compiled shader. Outside a shader they are ordinary global functions, so you can also use them in _update and _draw.

Unless noted, a function takes a number or a vector and works on each component. Where a function takes several arguments, a plain number can stand in for a vector: max(p, 0), mix(a, b, 0.5).

Type Made with Components
number 0.5
vec2 vec2(x, y) or vec2(v) .x .y
vec3 vec3(x, y, z), vec3(v2, z), vec3(v) .x .y .z or .r .g .b
vec4 vec4(x, y, z, w), vec4(v3, w), vec4(v2, z, w), vec4(v) .x .y .z .w or .r .g .b .a

A constructor takes any mix of numbers and vectors that adds up to the right count, or a single number that is repeated. Several component letters at once give a vector: p.xy, p.yx, c.bgr.

Operator Meaning
+ - * / Per component. A number combines with any vector; two vectors must be the same size
// Divide and round down
% Remainder, with the sign of the right side, the same as mod
^ Power
-v Negate
< > <= >= == ~= Compare two numbers. The result is true or false
and or not Combine comparisons
Function Returns
sin(v), cos(v), tan(v) Angle in radians
asin(v), acos(v) The angle whose sine or cosine is v
atan(v) The angle whose tangent is v
atan(y, x) The angle of the point x, y, from -π to π

sin, cos and tan are the panel’s own implementations. They are accurate to about seven digits and give exactly the same result on every panel. Angles beyond about ±4 million radians count as 0.

Function Returns
sqrt(v) Square root
pow(a, b) a to the power b; the same as a ^ b
exp(v) e to the power v
log(v) Natural logarithm

pow, exp, log, asin, acos and atan are the slowest functions on the panel. v * v is far cheaper than pow(v, 2.5); the compiler does turn v ^ 2 into a multiply for you.

Function Returns
floor(v) The whole number at or below v
ceil(v) The whole number at or above v
fract(v) The part after the decimal point: v - floor(v)
abs(v) Without its sign
sign(v) -1, 0 or 1
mod(a, b) Remainder: a - floor(a / b) * b
Function Returns
min(a, b), max(a, b) The smaller, the larger
clamp(v, lo, hi) v kept between lo and hi
step(edge, v) 0 where v < edge, otherwise 1
smoothstep(lo, hi, v) 0 below lo, 1 above hi, a smooth curve between
mix(a, b, t) a when t is 0, b when t is 1, a blend between
Function Returns
dot(a, b) A number: the dot product of two vectors of the same size
length(v) A number: the length of v
distance(a, b) A number: the length of a - b
normalize(v) v scaled to length 1
cross(a, b) The cross product of two vec3
Function Returns
hash(n), hash(v2) A fixed pseudo-random number from 0 up to 1 for each whole-number position
noise(x, y), noise(v2) Smooth noise from 0 to 1: a blend between the hashes at the four surrounding whole-number positions
fbm(x, y, octaves), fbm(v2, octaves) Layered noise. octaves is a whole number from 1 to 8 written in the code, not a variable

Each octave of fbm adds detail at twice the frequency and half the strength, and costs as much as one noise. Four octaves is a good default. hash looks only at the whole-number part of its input, so scale the coordinates to choose the cell size: hash(floor(x / 8)).

math.pi is available. Other constants are yours to define at the top of the script: local TAU = 6.2831853.

math.sin, math.floor and the rest of Lua’s math table take single numbers only. Inside a shader the panel adds math.fract, math.mix, math.clamp, math.smoothstep, math.step, math.mod, math.pow, math.sign, math.hash, math.noise and math.fbm, also for single numbers. Use the plain names when you have vectors.

local sin = math.sin -- fine: a short name for the scalar function
function fragment(x, y, u)
local p = vec2(x, y) * 0.1
local wave = sin(p.x) -- a number in, a number out
local both = cos(p) -- the plain name works on the whole vector
return 0.5 + 0.5 * wave, 0.5 + 0.5 * both.y, 0.3
end