1 GLSL Reference
A quick reference for the GLSL shading language as used in Shadertoy.
1.1 1. Types
Scalars
float x = 1.0; // floating point (always use decimal)
int i = 5; // integer
bool b = true; // booleanVectors
Vectors hold 2, 3, or 4 components of the same type:
vec2 p = vec2(1.0, 2.0); // 2 floats
vec3 color = vec3(1.0, 0.5, 0.0); // 3 floats
vec4 rgba = vec4(1.0, 0.5, 0.0, 1.0); // 4 floats
ivec2 pixel = ivec2(10, 20); // 2 ints
ivec3 coords = ivec3(1, 2, 3); // 3 ints
bvec2 flags = bvec2(true, false); // 2 boolsMatrices
Matrices are column-major (columns are listed first):
mat2 m2; // 2×2 matrix
mat3 m3; // 3×3 matrix
mat4 m4; // 4×4 matrixA mat2 holds 4 floats, a mat3 holds 9, a mat4 holds 16.
Samplers
Used to read from textures and buffers:
sampler2D tex; // 2D texture (you won't declare these yourself in Shadertoy)1.2 2. Components and Constructors
Component Access
Vectors have named components. Two naming conventions exist — use whichever fits your context:
vec4 v = vec4(1.0, 2.0, 3.0, 4.0);
// Position names
v.x, v.y, v.z, v.w // 1.0, 2.0, 3.0, 4.0
// Color names (equivalent)
v.r, v.g, v.b, v.a // 1.0, 2.0, 3.0, 4.0For vec2, only .xy or .rg are available. For vec3, .xyz or .rgb.
Rearranging Components
You can read multiple components at once, in any order:
vec3 v = vec3(1.0, 2.0, 3.0);
vec2 a = v.xy; // (1.0, 2.0)
vec2 b = v.yx; // (2.0, 1.0)
vec3 c = v.zyx; // (3.0, 2.0, 1.0)
vec3 d = v.xxx; // (1.0, 1.0, 1.0)This also works for assignment:
v.xy = v.yx; // swap x and yConstructors
Vectors can be built from scalars, smaller vectors, or combinations:
vec3 a = vec3(1.0); // (1.0, 1.0, 1.0)
vec3 b = vec3(1.0, 2.0, 3.0); // (1.0, 2.0, 3.0)
vec2 p = vec2(1.0, 2.0);
vec3 c = vec3(p, 3.0); // (1.0, 2.0, 3.0)
vec4 d = vec4(p, p); // (1.0, 2.0, 1.0, 2.0)
vec3 color = vec3(0.5, 0.7, 1.0);
vec4 rgba = vec4(color, 1.0); // (0.5, 0.7, 1.0, 1.0)1.3 3. Operators
Arithmetic on Vectors
Arithmetic operators work component-wise:
vec3 a = vec3(1.0, 2.0, 3.0);
vec3 b = vec3(4.0, 5.0, 6.0);
a + b // (5.0, 7.0, 9.0)
a - b // (-3.0, -3.0, -3.0)
a * b // (4.0, 10.0, 18.0) — component-wise, NOT dot product
a / b // (0.25, 0.4, 0.5)Scalar-Vector Operations
A scalar operates on each component:
vec3 v = vec3(1.0, 2.0, 3.0);
v * 2.0 // (2.0, 4.0, 6.0)
v + 1.0 // (2.0, 3.0, 4.0)
1.0 / v // (1.0, 0.5, 0.333...)Matrix-Vector Multiplication
Matrix times vector applies the linear transformation:
mat2 m = mat2(cos(a), sin(a), -sin(a), cos(a)); // rotation matrix
vec2 v = vec2(1.0, 0.0);
vec2 rotated = m * v; // matrix on the leftFor mat3 * vec3 and mat4 * vec4, same pattern.
1.4 4. Built-in Functions
Trigonometric
All angles are in radians.
| Function | Description |
|---|---|
sin(x) |
Sine |
cos(x) |
Cosine |
tan(x) |
Tangent |
asin(x) |
Arc sine, returns \([-\pi/2, \pi/2]\) |
acos(x) |
Arc cosine, returns \([0, \pi]\) |
atan(y, x) |
Arc tangent of y/x, returns \([-\pi, \pi]\) |
atan(y_over_x) |
Arc tangent, returns \([-\pi/2, \pi/2]\) |
Exponential
| Function | Description |
|---|---|
pow(x, y) |
\(x^y\) |
exp(x) |
\(e^x\) |
log(x) |
\(\ln(x)\) |
exp2(x) |
\(2^x\) |
log2(x) |
\(\log_2(x)\) |
sqrt(x) |
\(\sqrt{x}\) |
inversesqrt(x) |
\(1/\sqrt{x}\) |
Common
| Function | Description |
|---|---|
abs(x) |
Absolute value |
sign(x) |
Returns \(-1\), \(0\), or \(1\) |
floor(x) |
Largest integer \(\leq x\) |
ceil(x) |
Smallest integer \(\geq x\) |
fract(x) |
\(x - \text{floor}(x)\), the fractional part |
mod(x, y) |
\(x - y \cdot \text{floor}(x/y)\) |
min(x, y) |
Minimum |
max(x, y) |
Maximum |
clamp(x, lo, hi) |
Clamps x to \([\text{lo}, \text{hi}]\) |
mix(a, b, t) |
Linear interpolation: \(a(1-t) + bt\) |
step(edge, x) |
\(0\) if \(x < \text{edge}\), else \(1\) |
smoothstep(e0, e1, x) |
Smooth transition from 0 to 1 |
Geometric
| Function | Description |
|---|---|
length(v) |
Euclidean length \(\|v\|\) |
distance(a, b) |
Distance \(\|a - b\|\) |
dot(a, b) |
Dot product \(a \cdot b\) |
cross(a, b) |
Cross product (vec3 only) |
normalize(v) |
Unit vector \(v / \|v\|\) |
reflect(I, N) |
Reflection of I about normal N |
refract(I, N, eta) |
Refraction with index ratio eta |
Gotchas
atan(y, x) not atan(x, y) — The two-argument arctangent takes y first:
float angle = atan(p.y, p.x); // correct
float angle = atan(p.x, p.y); // wrong — rotated 90°mod on negatives — The result has the same sign as the divisor:
mod(-0.5, 1.0) // returns 0.5, not -0.5
mod(-1.5, 1.0) // returns 0.5This is usually what you want for wrapping coordinates, but can surprise you.
pow with negative base — Undefined for non-integer exponents:
pow(-2.0, 2.0) // undefined (may return NaN or 0)
pow(abs(x), y) // safe alternative1.5 5. Shadertoy Uniforms
Shadertoy provides these global variables:
Resolution and Time
| Uniform | Type | Description |
|---|---|---|
iResolution |
vec3 |
Viewport resolution in pixels (.xy is width, height) |
iTime |
float |
Seconds since shader started |
iTimeDelta |
float |
Seconds since last frame |
iFrame |
int |
Frame number (starts at 0) |
Mouse
iMouse is a vec4:
| Component | Description |
|---|---|
iMouse.xy |
Current mouse position (pixels) while button held, else last click position |
iMouse.zw |
Position where button was pressed (positive if currently held, negative after release) |
Common patterns:
// Normalize mouse to [0, 1]
vec2 mouse = iMouse.xy / iResolution.xy;
// Check if mouse button is held
bool mouseDown = iMouse.z > 0.0;Channels
| Uniform | Type | Description |
|---|---|---|
iChannel0 – iChannel3 |
sampler2D |
Texture or buffer inputs |
iChannelResolution[0–3] |
vec3 |
Resolution of each channel |
Date
| Uniform | Type | Description |
|---|---|---|
iDate |
vec4 |
(year, month, day, seconds since midnight) |
1.6 6. Textures & Buffers
Reading Textures
Interpolated sampling — UV coordinates in \([0, 1]\):
vec4 color = texture(iChannel0, uv);The texture wraps or clamps depending on Shadertoy settings for that channel.
Exact pixel fetch — integer coordinates:
vec4 color = texelFetch(iChannel0, ivec2(x, y), 0);The third argument (0) is the mipmap level; always use 0 in Shadertoy.
Buffers
Shadertoy provides four buffers: Buf A, Buf B, Buf C, Buf D. Each runs its own shader and outputs to a texture you can read from other tabs.
Reading the previous frame (for simulations):
- In Buf A, set
iChannel0to point to Buf A itself - Read with
texelFetch(iChannel0, ivec2(fragCoord), 0) - Write new state to
fragColor
// In Buffer A
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
ivec2 px = ivec2(fragCoord);
vec4 prev = texelFetch(iChannel0, px, 0); // previous frame
// ... compute new state ...
fragColor = newState;
}Reading a buffer in Image:
Set iChannel0 (or any channel) to the buffer, then sample it:
// In Image
vec4 state = texelFetch(iChannel0, ivec2(fragCoord), 0);The Common Tab
Code in the Common tab is included in all other tabs. Use it for:
- Shared constants (
const float PI = 3.14159;) - Shared functions (
vec3 hsv2rgb(...)) - Shared struct definitions
// In Common
const float PI = 3.14159265359;
const float TAU = 6.28318530718;
vec3 hsv2rgb(vec3 c) {
vec3 p = abs(fract(c.xxx + vec3(0.0, 2.0/3.0, 1.0/3.0)) * 6.0 - 3.0);
return c.z * mix(vec3(1.0), clamp(p - 1.0, 0.0, 1.0), c.y);
}1.7 7. Syntax Pitfalls
Floats Need Decimals
float x = 1; // ERROR
float x = 1.0; // correct
vec3 v = vec3(1, 2, 3); // ERROR (in some contexts)
vec3 v = vec3(1.0, 2.0, 3.0); // correctFunctions Must Be Declared Before Use
Unlike C, there are no forward declarations. Define helper functions above mainImage:
// This must come first
float sdf(vec3 p) {
return length(p) - 1.0;
}
// Then this can call it
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
// ... sdf(p) works here ...
}No Overloading by Return Type
You can overload by parameter types, but not by return type alone:
float foo(float x) { return x; }
vec3 foo(float x) { return vec3(x); } // ERROR — conflicts with aboveConstants
Use const for compile-time constants:
const float PI = 3.14159265359;
const int MAX_STEPS = 100;
const vec3 LIGHT_DIR = normalize(vec3(1.0, 1.0, 1.0));These can be used in loop bounds and array sizes (unlike regular variables).
Integer Division
Division between integers is integer division:
int a = 5 / 2; // a = 2, not 2.5
float b = 5 / 2; // b = 2.0 (still integer division, then converted)
float c = 5.0 / 2.0; // c = 2.5 (correct)