📅 March 2026⏱ Quick reference🎯 GLSL ES 3.0 (WebGL 2)
GLSL Built-in Functions Quick Reference
All GLSL ES 3.0 built-in functions grouped by category — math,
geometry, texture, derivatives, matrix, and type constructors — with
signatures, behaviour notes, and WebGL-specific gotchas. Bookmark this
when writing shaders.
1. Type Notation and genType
GLSL built-in signatures use generic type names. A function listed as
taking genType
actually has overloads for all of the following:
Alias
Expands to
genType
float, vec2, vec3, vec4
genIType
int, ivec2, ivec3, ivec4
genUType
uint, uvec2, uvec3, uvec4
genBType
bool, bvec2, bvec3, bvec4
mat
mat2, mat3, mat4, mat2x3, mat2x4…
gsampler2D
sampler2D, isampler2D, usampler2D
When a function takes genType x, genType y, both
arguments must have the same type and dimension — you cannot mix
vec3 and float without an explicit cast.
GLSL ES 3.0 vs 1.0: WebGL 1 uses GLSL ES 1.00 (no
integers, no textureSize, no dFdx in some implementations). WebGL 2
uses GLSL ES 3.00 — requires #version 300 es at the top
of the shader. All functions in this reference are GLSL ES 3.0 unless
marked 1.0.
2. Angle and Trigonometry Functions
All trig functions operate on radians. Input/output are
genType.
Function
Description
Notes
radians(d)
degrees → radians
= d · π/180
degrees(r)
radians → degrees
= r · 180/π
sin(x)
Sine
Range [−1, 1]
cos(x)
Cosine
Range [−1, 1]
tan(x)
Tangent
Undefined at π/2 + kπ
asin(x)
Arc sine
UB if |x| > 1; returns [−π/2, π/2]
acos(x)
Arc cosine
UB if |x| > 1; returns [0, π]
atan(y, x)
atan2 — full-range arc tangent
Returns [−π, π]; preferred over atan(y/x)
atan(y_over_x)
Single-arg arc tangent
Returns [−π/2, π/2]; use two-arg form at ±π boundary
sinh(x)
Hyperbolic sine
(eˣ − e⁻ˣ)/2
cosh(x)
Hyperbolic cosine
(eˣ + e⁻ˣ)/2; always ≥ 1
tanh(x)
Hyperbolic tangent
Range (−1, 1)
asinh(x)
Inverse hyperbolic sine
Defined for all x
acosh(x)
Inverse hyperbolic cosine
UB if x < 1
atanh(x)
Inverse hyperbolic tangent
UB if |x| ≥ 1
sin/cos wrap trick: If you accumulate a time variable
and pass it to sin/cos, once the float exceeds ~10⁵ the period will
drift on mediump. Use:
float t = mod(uTime, 6.2831853); to keep precision.
3. Exponential and Logarithm Functions
Function
Description
Notes
pow(x, y)
x^y
UB if x < 0; if x=0 and y≤0, UB. Prefer
exp(y*log(x)) if y is dynamic.
exp(x)
eˣ
Overflows to +∞ for large x; use exp2 for base-2
log(x)
ln(x)
UB if x ≤ 0
exp2(x)
2ˣ
Hardware-accelerated on most GPUs
log2(x)
log₂(x)
UB if x ≤ 0. Faster than log on many GPUs.
sqrt(x)
√x
UB if x < 0. For vectors, component-wise.
inversesqrt(x)
1/√x
UB if x ≤ 0. Use this instead of 1.0/sqrt(x) — one
GPU instruction.
4. Common Math Functions
Function
Description
Notes
abs(x)
|x| component-wise
Works for int, uint, float vectors
sign(x)
−1, 0, or +1 per component
sign(0.0) = 0.0
floor(x)
Largest integer ≤ x (as float)
floor(−0.5) = −1.0
ceil(x)
Smallest integer ≥ x
ceil(−0.5) = 0.0
trunc(x)
Round toward zero
ES 3.0 only. trunc(−0.9) = 0.0
round(x)
Round to nearest; ties → even
ES 3.0 only. "Banker's rounding"
roundEven(x)
Round half to even (IEEE)
ES 3.0 only
fract(x)
x − floor(x)
Always in [0, 1). fract(−0.3) = 0.7
mod(x, y)
x − y·floor(x/y)
Result sign matches y (not x). For negative x: mod(−1.0, 4.0) =
3.0
modf(x, out i)
Returns fract(x); i = trunc(x)
i is an out parameter
min(x, y)
Component-wise minimum
y can be scalar (broadcast)
max(x, y)
Component-wise maximum
y can be scalar
clamp(x, lo, hi)
max(lo, min(hi, x))
UB if lo > hi
mix(x, y, a)
Lerp: x·(1−a) + y·a
a can be bool vector: mix(x,y,bvec) selects components
step(edge, x)
0 if x < edge; 1 otherwise
edge can be scalar or same type as x
smoothstep(e0,e1,x)
Hermite interpolation 0→1
UB if e0 ≥ e1. = t²(3−2t) where t=clamp((x−e0)/(e1−e0),0,1)
isnan(x)
true if x is NaN
ES 3.0 only. Returns bvec/bool
isinf(x)
true if x is ±Infinity
ES 3.0 only
floatBitsToInt(v)
Re-interpret bits as int
ES 3.0 only. No conversion — raw bit access
intBitsToFloat(v)
Re-interpret int bits as float
ES 3.0 only
packSnorm2x16(v)
Pack vec2 to uint
ES 3.0 only
unpackSnorm2x16(p)
Unpack uint to vec2
ES 3.0 only
// Common snippet: smooth hash noise
float hash(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
// Safe smoothstep guard
float ss = smoothstep(0.2, 0.8, uv.x); // always e0 < e1
// Select between two values with step (no branch):
vec3 col = mix(colorA, colorB, step(0.5, uv.x));
5. Geometric Functions
Function
Signature
Description
length(x)
float length(genType x)
Euclidean length √(x²+y²+…). For vec3: √(x²+y²+z²)
1.0 Equivalent to texture() in ES
1.00 fragment shaders. Not available in ES 3.00.
// Data texture (ping-pong simulation state):
uniform sampler2D uState;
uniform vec2 uRes;
vec4 readCell(ivec2 coord) {
coord = clamp(coord, ivec2(0), ivec2(uRes) - 1);
return texelFetch(uState, coord, 0); // exact integer texel, no filtering
}
// Neighbour sum (Conway / reaction-diffusion):
ivec2 px = ivec2(gl_FragCoord.xy);
vec4 c = readCell(px);
vec4 L = readCell(px + ivec2(-1, 0));
vec4 R = readCell(px + ivec2( 1, 0));
vec4 U = readCell(px + ivec2( 0, 1));
vec4 D = readCell(px + ivec2( 0,-1));
8. Fragment Derivative Functions
Fragment derivative functions are only available in the fragment
shader. They compute the rate of change of a value across neighbouring
fragment quads.
Function
Description
dFdx(p)
Partial derivative of p with respect to window x (screen-space
column). frag only
dFdy(p)
Partial derivative with respect to y (screen-space row). Sign
convention: y+ is up in GLSL.
frag only
fwidth(p)
= abs(dFdx(p)) + abs(dFdy(p)). Approximates "one pixel
footprint" at any position.
frag only
dFdxFine(p)
ES 3.2 only. Fine-grained 2×1 quad derivative (not widely
supported in WebGL). frag only
dFdxCoarse(p)
ES 3.2 only. 2×2 quad derivative (cheaper, less accurate).
frag only
Anti-aliased Shapes with fwidth
// Anti-aliased circle (no MSAA needed):
float circle(vec2 uv, float r) {
float d = length(uv) - r;
float w = fwidth(d); // 1 pixel in distance units
return 1.0 - smoothstep(-w, w, d);
}
// Anti-aliased grid lines:
float grid(vec2 uv, float spacing) {
vec2 g = abs(fract(uv / spacing - 0.5) - 0.5);
vec2 w = fwidth(uv / spacing);
vec2 line = smoothstep(vec2(0.0), w * 1.5, g);
return 1.0 - min(line.x, line.y);
}
Precision qualifier reminder:
In WebGL fragment shaders, the default float precision is
not defined — you must declare it:
precision highp float; at the top of every fragment
shader. mediump has only ~13 bits of mantissa —
equivalent to about 3 decimal digits. Use highp for
positions, UVs, and any calculation where you need >3 significant
digits.
Availability check: In WebGL 1 (GLSL ES 1.00),
derivative functions require the
OES_standard_derivatives extension: call
gl.getExtension('OES_standard_derivatives') and add
#extension GL_OES_standard_derivatives : enable at shader
top. In WebGL 2 / GLSL ES 3.00 they are always available.