1983 · ORIGINAL
2002 · IMPROVED
Ken Perlin · Gradient Noise · Live Render

One noise,
19832002

The same field, computed two ways. Left of the seam: the original algorithm — a table of 256 random gradients and a cubic ease curve. Right: the Improved version — 12 fixed gradients and a quintic fade. Drag the seam. Then scroll to see why each choice was made, and what breaks without it.

v1 · G[256] + 3t²−2t³ v2 · 12 vectors + 6t⁵−15t⁴+10t³
The pipeline

Five steps, two revisions

Both versions run the same five-step pipeline. The 2002 revision touched exactly two of the steps — the gradients and the ease curve — and simplified the machinery around a third.

01lattice

Snap to the unit-cube grid

both

Floor the input to find its cell, keep the fractional part xf = x − ⌊x⌋, and wrap cell indices with & 255. Cheap, but it means the noise repeats every 256 units — invisible in practice because you sample at fractional coordinates.

unchanged
02hash

Hash every cell corner

1983

Nested permutation lookups G[(i + P[(j + P[k]) & 255]) & 255] — the hash is only an index into a second table, G, that stores actual gradient vectors.

2002

Same doubled p[512] table hashes each of the 8 corners — but the hash is the gradient now: its low 4 bits pick a vector directly. The whole G table disappears.

table removed
03gradients

Pick a gradient per corner

1983

256 precomputed pseudorandom unit vectors — every direction equally likely, which is elegant but lets gradients clump near the coordinate axes by chance.

2002

Just 12 vectors, from the cube's center to its edge midpoints: (±1,±1,0), (±1,0,±1), (0,±1,±1). No axis-aligned bias, and every dot product collapses into adds and subtracts — zero multiplies.

256 → 12
04influence

Dot products at 8 corners

both

dot(gradient, point − corner) — positive downhill of the gradient, negative against it, zero perpendicular. A side effect both versions share: the noise is exactly 0 at every lattice point, because the distance vector there is zero.

unchanged
05blend

Ease, then interpolate

1983

Warp t with 3t² − 2t³ before the trilinear lerp. Continuous slope (C¹) — but its second derivative jumps at every cell wall, which surfaces as creases the moment you compute normals for bump mapping.

2002

Swap in 6t⁵ − 15t⁴ + 10t³. First and second derivatives are both zero at the endpoints (C²), so derivative-based effects come out clean.

C¹ → C²
+finish

Octaves (the standard post-process)

extra

Not part of either core algorithm — but almost every real use sums several noises at frequency = 2ⁱ, amplitude = persistenceⁱ to layer mountains over hills over pebbles. Lab 03 below.

both eras
Lab 01 · the ease curve

No ease → cubic → quintic

Gradients are held fixed (v2's 12 vectors) — only the interpolant changes. The raw noise looks similar in all three. Switch the view to slope or curvature to see where each simpler choice breaks: artifacts show up as straight, grid-aligned seams.

Interpolant
View
f, f′, f″ across one cell. A neighboring cell sees the mirrored curve — any nonzero endpoint value (○) becomes a visible seam of that order at the cell wall.
Lab 02 · what lives on the lattice

Values → random gradients → 12 vectors

The fade is held fixed (v2's quintic) — only the thing stored at each lattice corner changes. The simplest idea, storing plain random values, isn't Perlin noise at all — it's value noise, and its energy visibly clings to the grid.

Lattice contents
Lab 03 · octaves

One octave vs. a fractal sum

A single octave of Perlin noise is smooth but featureless — nature has detail at every scale. Layering octaves at doubling frequency and shrinking amplitude (set by persistence) is what turns wobble into terrain.

Octaves 4
Persistence 0.50
Amplitude budget per octave: frequency = 2ⁱ, amplitude = persistenceⁱ, then the sum is renormalized to keep the range stable.
Cost is linear in octaves — each layer is a full noise evaluation, so real-time effects keep to a few octaves while offline terrain generation can afford many.