Noise Function Family Tree
Value Noise
Random values at integer lattice points, interpolated. Fast. Low quality. Good for prototyping.
Gradient (Perlin)
Random gradient vectors at lattice points, dot-producted and interpolated. Smooth, no banding.
Simplex Noise
Perlin on a simplex lattice. Fewer directional artifacts, O(n²) in n dimensions vs O(2ⁿ).
Worley (Cell) Noise
Distance to the nearest random seed point. Produces stone-tile, cell, bubble patterns.
FBm
Fractional Brownian Motion — sums of noise at increasing frequencies (octaves). Fractal detail.
Domain Warping
Feed a noise-displaced position into another noise call. Turbulence, smoke, fire.
The Hash Function — Foundation of Everything
All the noise functions above need a pseudo-random value at every integer lattice point. The hash function converts an integer coordinate into a float in [0,1). The fastest reliable option in GLSL is a single-line sine/fract trick, though for production quality a 32-bit integer Wang hash is better:
// Quick and dirty (sin-based, some GPUs have precision issues)
float hash11(float n) { return fract(sin(n) * 43758.5453); }
vec2 hash21(float n) { return fract(sin(vec2(n,n+1.0)) * vec2(43758.5453,22578.1459)); }
// Better: integer Wang hash (requires GLSL 3.30 / ES 3.00 with uint)
uint wangHash(uint seed) {
seed = (seed ^ 61u) ^ (seed >> 16u);
seed *= 9u;
seed ^= seed >> 4u;
seed *= 0x27d4eb2du;
seed ^= seed >> 15u;
return seed;
}
float hashFloat(uint seed) { return float(wangHash(seed)) / 4294967296.0; }
Perlin Noise in GLSL
Classic gradient noise. Sample at position p, find the
surrounding four integer corners, assign a random gradient to each,
compute the dot product with the offset vector, and interpolate with a
smooth cubic or quintic fade function.
// Gradient directions (8 cardinal + diagonal, classic Perlin)
vec2 grad(vec2 p) {
float a = hash11(dot(p, vec2(127.1, 311.7))) * 6.2832;
return vec2(cos(a), sin(a));
}
float perlin(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
vec2 u = f*f*f*(f*(f*6.0-15.0)+10.0); // quintic interpolation
float a = dot(grad(i + vec2(0,0)), f - vec2(0,0));
float b = dot(grad(i + vec2(1,0)), f - vec2(1,0));
float c = dot(grad(i + vec2(0,1)), f - vec2(0,1));
float d = dot(grad(i + vec2(1,1)), f - vec2(1,1));
return mix(mix(a,b,u.x), mix(c,d,u.x), u.y);
}
Fractional Brownian Motion (FBm)
FBm is simply the sum of noise at multiple octaves — each octave doubles the frequency (lacunarity ≈ 2) and halves the amplitude (gain ≈ 0.5). This creates the self-similar fractal appearance of clouds, terrain, and turbulent fluids.
float fbm(vec2 p, int octaves, float lacunarity, float gain) {
float value = 0.0;
float amplitude = 0.5;
for (int i = 0; i < octaves; i++) {
value += amplitude * perlin(p);
p *= lacunarity; // frequency up
amplitude *= gain; // amplitude down
}
return value;
}
Domain Warping
Instead of evaluating fbm(pos), evaluate
fbm(pos + fbm(pos + offset1) + fbm(pos + offset2)). Each
layer displaces the sampling position of the next, creating turbulent,
organic structures that are impossible with simple FBm.
Domain warping = free non-linearity. Iq (Inigo Quilez) first documented this technique in 2002. Two levels of warp produce "turbulence"; three levels approach real-looking fire and smoke. Each extra warp level costs 1 additional FBm evaluation but delivers dramatically more visual complexity.
Live Noise-Based Simulations
These simulations use noise functions at their core — explore them to see the techniques above in action:
Procedural Textures
Value, Perlin, Simplex, Worley, and FBm rendered in real time — side by side comparison with controls.
3D Terrain Generator
Multi-octave FBm height map rendered with Three.js displacement — tune octaves, lacunarity, and gain live.
Procedural World Map
Domain-warped FBm drives biome classification: ocean, coast, plains, hills, mountains, peaks.
Voronoi / Worley Noise
Interactive Voronoi diagram where you drag seed points — visualise F1, F2, F2-F1 distance functions.
Barnsley Fern
Iterated function system fractal — structured self-similarity emerging from four affine transformations.
Fractal Explorer
Mandelbrot and Julia sets with smooth colouring — zoom into 10⁻¹⁵ scale detail with arbitrary precision.