Perlin Noise: Creating Structure From Randomness
The core problem with procedural generation is that randomness doesn't look natural. Call Math.random() for each pixel in a grid and you get static: every point independent of its neighbors. Nature doesn't work like that. A mountain peak implies slopes, which imply foothills. Adjacent points in the real world are correlated. Pure randomness has no correlation, so it has no structure.
Perlin noise solves this by working on a grid of random gradient vectors rather than random values. For any point you want to evaluate, the algorithm finds the four surrounding grid corners, computes the dot product between each corner's gradient and the vector from that corner to your point, then interpolates the results using a quintic curve (6t⁵ - 15t⁴ + 10t³) whose first and second derivatives are zero at the boundaries. The output is a single float that varies continuously across space with no seams between grid cells.
That continuity is useful, but a single layer of Perlin noise is too blobby to pass as terrain. The standard fix is fractal Brownian motion (fBm): layer multiple "octaves" of noise at increasing frequencies and decreasing amplitudes. The first octave defines mountains and valleys. The second adds ridges. The third adds rocks. Two parameters control the stacking: persistence (how quickly amplitude falls off per octave, typically 0.5) and lacunarity (how quickly frequency increases, typically 2.0). Crank persistence up and the terrain gets rougher. Drop it and everything smooths out.
In practice this shows up everywhere. Minecraft's world generation is fBm noise interpreted as a heightmap. No Man's Sky layers 3D noise fields to carve cave systems. Shader artists sample noise at varying scales to drive cloud density, ocean displacement, and fire turbulence in real-time. Noise-driven animation, sampling along the time axis instead of space, gives you organic camera shake and idle character motion that never loops.
Perlin noise works because it's cheap, tileable, deterministic (same seed = same world), and dimensional: the same algorithm generalizes from 1D (animation curves) through 2D (textures, heightmaps) to 3D (volumetric effects) and 4D (animated volumetrics). Most modern implementations actually use simplex noise, also by Perlin, which scales better to higher dimensions and avoids the directional artifacts you get from an axis-aligned grid. The conceptual framework is identical.