Skip to content

Perlin Noise

  • Perlin Noise is a procedural noise generation algorithm that produces natural-looking results.

Sample Perlin Noise

  • This is a sample of Perlin noise.

Perlin Noise Generation Algorithm

  • The following interactive diagram visualizes some steps of the Perlin Noise algorithm in a 6x6 grid.
    • Blue arrows show the random vectors at the corners and the vectors pointing from the corners to the point of interest.
    • Blue text shows the dot product of the above vector pairs.
    • Orange text on the sides shows the interpolated result of the left and right side dot products.
    • Green text shows the result value; it's always in the range [-1, 1].

Summary of the algorithm

  1. Make an array of length 256 where each index's value is the index, then shuffle it. For this step, Perlin has a canonical array which he calls the permutation table, accessible here.
  2. Generate an array of 256 random unit vectors. The indices in the permutation table are actually a key to look up vectors from this vectors array.
  3. Given a point in 2D P = (x, y), find the integer grid that it belongs to, whose top left corner index is (xi, yi) (presuming we are using the HTML canvas coordinate system where the y-axis points down). Then the indices for the other three corners are easily calculated: (xi + 1, yi), (xi, yi + 1), and (xi + 1, yi + 1).
  4. For each corner, find its corresponding unit vector. Note that the same corner always maps to the same random unit vector no matter which grid you calculate from. Perlin's formula for doing this is vectorIndex = permutation[permutation[xi] + yi], then cornerVector = randomVectorArray[vectorIndex].
  5. For each corner, make a vector from the corner to the point P. Then, take the dot product of this vector with that corner's unit vector. Now we have four dot products, one for each corner.
  6. Interpolate the four dot products into one. First, interpolate the two on the left side using f(a, b, t) where t = dy = y - yi, then the two on the right. Then interpolate the left and right with f(a, b, t) again where t = dx = x - xi. Here if we use simple linear interpolation we can get hard edges, so Perlin proposed a smooth function where t = 6*t^5 - 15*t^4 + 10*t^3.
  7. This gives the final value, which is always within the range [-1, 1]. To transform it to [0, 1], simply do v = (v+1)/2.

Improving Noise

  • Perlin published another paper in 2002 to improve the Perlin noise algorithm. The core of the paper is that instead of using random vectors in step 4, he randomly chooses between 4 vectors (from center to each edge of the rect). I implemented this variation with PerlinNoise.sampleImproved(), and it's toggle-able in the first visualization diagram on this page. I notice more dark areas and diagonal patterns with this version.

Resources