Perlin Noise

Perlin noise is a technique for adding apparent randomness to graphics, terrain, and other things. First created in 1985 by Ken Perlin, an improved algorithm was created in 2002 that fixed some visual issues. Perlin noise works by creating a grid and, for each point in the grid, generating a value that looks random, but is actually pre-defined.

Algorithm (2002)
This is the Perlin noise algorithm in its original Java implementation. public final class ImprovedNoise { static public double noise(double x, double y, double z) { int X = (int)Math.floor(x) & 255,                 // FIND UNIT CUBE THAT Y = (int)Math.floor(y) & 255,                 // CONTAINS POINT. Z = (int)Math.floor(z) & 255; x -= Math.floor(x);                               // FIND RELATIVE X,Y,Z y -= Math.floor(y);                               // OF POINT IN CUBE. z -= Math.floor(z); double u = fade(x),                               // COMPUTE FADE CURVES v = fade(y),                               // FOR EACH OF X,Y,Z. w = fade(z); int A = p[X ]+Y, AA = p[A]+Z, AB = p[A+1]+Z,      // HASH COORDINATES OF           B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z;      // THE 8 CUBE CORNERS, return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y  , z   ),  // AND ADD                                      grad(p[BA  ], x-1, y  , z   )), // BLENDED lerp(u, grad(p[AB ], x , y-1, z   ),  // RESULTS                                      grad(p[BB  ], x-1, y-1, z   ))),// FROM  8                      lerp(v, lerp(u, grad(p[AA+1], x  , y  , z-1 ),  // CORNERS                                      grad(p[BA+1], x-1, y  , z-1 )), // OF CUBE lerp(u, grad(p[AB+1], x, y-1, z-1 ),                                      grad(p[BB+1], x-1, y-1, z-1 )))); }   static double fade(double t) { return t * t * t * (t * (t * 6 - 15) + 10); } static double lerp(double t, double a, double b) { return a + t * (b - a); } static double grad(int hash, double x, double y, double z) { int h = hash & 15;                     // CONVERT LO 4 BITS OF HASH CODE double u = h<8 ? x : y,                // INTO 12 GRADIENT DIRECTIONS. v = h<4 ? y : h==12||h==14 ? x : z;      return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); }   static final int p[] = new int[512], permutation[] = { 151,160,137,91,90,15, 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,   190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,    88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,    77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,    102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,    135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,    5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,    223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,    129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,    251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,    49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,    138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180    };    static { for (int i=0; i < 256 ; i++) p[256+i] = p[i] = permutation[i]; } }

Perlin Noise Explained
There are a few things the algorithm does before actually generating noise. First it creates an array called p, which has 512 elements. In the p array is that large block of numbers stored twice. That block of numbers is every number from 0 to 255, and is where the heart of Perlin noise's apparent randomness comes from.

This implementation assumes you pass three floating point numbers, for example 3.14, 2.78, and 9.19. It then imagines the point is somewhere on a three-dimensional grid, and finds which cube on that grid the point is located in. Our example numbers would give us X = 3, Y = 2, and Z = 9. After this, the algorithm finds the location of the point within that cube on the grid. Our example numbers would give x = 0.14, y = 0.78, and z = 0.19.

Next the algorithm runs a fade function, also known as an ease curve, on x, y, and z. In this case it's just a mathematical expression, namely 6t5- 15t4 + 103. This makes the eventual output of the algorithm more varied and interesting.

The output of Perlin's noise algorithm is a number between 0 and 1. Without the fade curve, how quickly output moved from 0 to 1 along the cube grid would be linear - that is, it would be the same amount every unit moved. This is neither realistic nor visually interesting. The fade function makes it so that the rate of change varies. When the point is closer to 0 or 1, the rate of change is more gradual. When the point is closer to the center, that rate of change is quicker.

The next part of the algorithm finds numbers for the six faces of the grid cube. Finally the gradient vectors for the eight corners of the cube are found. The gradient vector is either -1, 0, or 1. Four pairs of gradient vectors are then run through a linear interpolation, which essentially just looks for their middle point, influenced by the fade function. These four values are again interpolated in pairs, and the last pair is interpolated and returned as the result. This result is the Perlin noise value.

Minecraft
Minecraft makes extensive use of Perlin noise and related algorithms, in order to generate world terrain. A Minecraft world is composed of biomes, such as deserts, grassy plains, forests, mountains, and more. Perlin noise is used to generate these biomes. It is also used to determine how terrain is generated in that biome, even down to the locations of trees and the style of their leaves. For example, a desert is flatter than a mountain biome.

Code Examples
The code examples are found in the perlin folder of the repository.

Perlin Implementation in Python
In the code respository is a Python port of the original Java code, as well as a simple test program. You can enter three numbers and see what the algorithm outputs. Try not to input just whole numbers like 1.0, 2.0, etc. If you give it all whole numbers the output will be 0.0. This is a known feature of Perlin noise.

Biomes Example
This example procedurally generates a 2D map that you can scroll up, down, left, and right in. Perlin noise is used to determine the biome of the block. Grass biomes are forest green, deserts are yellow, and snowy biomes are white. Navigate using the WASD keys.

Galaxy Example
This is an elaboration on the biomes example. It generates a three-dimensional galaxy, really just a grid of stars. Two instances of Perlin noise are used to generate the stars: the first to determine star size, and one to determine star color. If you click on a star you can visit its solar system. Clicking on a planet lets you view its surface in a style similar to the biomes example. Use WASD to navigate the current layer of stars, and QE to go up or down a layer.