Perlin noise

Perlin noise is a type of gradient noise developed by Ken Perlin in 1983 as a result of his frustration with the "machine-like" look of computer-generated imagery (CGI) at the time.[1] He formally described his findings in a SIGGRAPH paper in 1985 called An image Synthesizer.[2] In 1997, Perlin was awarded an Academy Award for Technical Achievement for creating the algorithm.[3][4]

To Ken Perlin for the development of Perlin Noise, a technique used to produce natural appearing textures on computer generated surfaces for motion picture visual effects. The development of Perlin Noise has allowed computer graphics artists to better represent the complexity of natural phenomena in visual effects for the motion picture industry.

Two-dimensional slice through 3D Perlin noise at z=0

Perlin did not apply for any patents on the algorithm, but in 2001 he was granted a patent for the use of 3D+ implementations of simplex noise for texture synthesis. Simplex noise has the same purpose, but uses a simpler space-filling grid. Simplex noise alleviates some of the problems with Perlin's "classic noise", among them computational complexity and visually-significant directional artifacts.[5]

Uses

A virtual landscape generated using Perlin noise

Perlin noise is a procedural texture primitive, a type of gradient noise used by visual effects artists to increase the appearance of realism in computer graphics. The function has a pseudo-random appearance, yet all of its visual details are the same size. This property allows it to be readily controllable; multiple scaled copies of Perlin noise can be inserted into mathematical expressions to create a great variety of procedural textures. Synthetic textures using Perlin noise are often used in CGI to make computer-generated visual elements  such as object surfaces, fire, smoke, or clouds  appear more natural, by imitating the controlled random appearance of textures in nature.

An organic surface generated with Perlin noise

It is also frequently used to generate textures when memory is extremely limited, such as in demos. Its successors, such as fractal noise and simplex noise, have become nearly ubiquitous in graphics processing units both for real-time graphics and for non-realtime procedural textures in all kinds of computer graphics.

Development

Perlin noise resulted from the work of Ken Perlin, who developed it at Mathematical Applications Group, Inc. (MAGI) for Disney's computer animated sci-fi motion picture Tron (1982). In 1997, he won an Academy Award for Technical Achievement from the Academy of Motion Picture Arts and Sciences for this contribution to CGI.[6]

Algorithm detail

Perlin noise rescaled and added into itself to create fractal noise.

Perlin noise is most commonly implemented as a two-, three- or four-dimensional function, but can be defined for any number of dimensions. An implementation typically involves three steps: grid definition with random gradient vectors, computation of the dot product between the distance-gradient vectors and interpolation between these values. [7]

Grid definition

A 2-dimensional grid of gradient vectors

Define an n-dimensional grid where each point has a random n-dimensional unit-length gradient vector, except in the one dimensional case where the gradients are random scalars between -1 and 1.

Assigning the random gradients in one and two dimensions is trivial using a random number generator. For higher dimensions a Monte Carlo approach can be used[1] where random Cartesian coordinates are chosen in a unit cube, points falling outside the unit ball are discarded, and the remaining points are normalized to lie on the unit sphere. The process is continued until the required number of random gradients are obtained.

In order to negate the expensive process of computing new gradients for each grid node, some implementations use a hash and lookup table for a finite number of precomputed gradient vectors.[8] The use of a hash also permits the inclusion of a random seed where multiple instances of Perlin noise are required.

Dot product

The dot product of each point with its nearest grid node gradient value. The dot product with the other three nodes in the cell is not shown.

Once an n-dimensional gradient value is generated for each node along the n-dimensional grid, the next series of steps produce values specific to the candidate point one wishes to obtain noise values for.

An n-dimensional candidate point can be viewed as falling into an n-dimensional grid cell, where the corners are the n-dimensional grid defined previously. Fetch the closest gradient values, located at the corners of the grid cell the candidate point falls into. Then, for each gradient value, compute a distance vector defined as the offset vector from each corner node to the candidate point. After that, compute the dot product between each pair of gradient vector and distance offset vector. This function has a value of 0 at the node and a gradient equal to the precomputed node gradient.

For a point in a two-dimensional grid, this will require the computation of 4 distance vectors and dot products, while in three dimensions 8 distance vectors and 8 dot products are needed. This leads to the complexity scaling.

Interpolation

The final interpolated result

The final step is interpolation between the dot products computed at the nodes of the cell containing the argument point. Interpolation is performed using a function that has zero first derivative (and possibly also second derivative) at the grid nodes. Therefore, at points close to the grid nodes the output will approximate the dot product from earlier. This means that the noise function will pass through zero at every node and have a gradient equal to the precomputed grid node gradient. These properties give Perlin noise its characteristic spatial scale.

If , an example of a function that interpolates between value at grid node 0 and value at grid node 1 is

where the smoothstep function was used.

Noise functions for use in computer graphics typically produce values in the range [-1.0,1.0]. In order to produce Perlin noise in this range, the interpolated value may need to be scaled by some scaling factor.[8]

Implementation

The following is a two-dimensional implementation of Classical Perlin Noise, written in C.

/* Function to linearly interpolate between a0 and a1
 * Weight w should be in the range [0.0, 1.0]
 *
 * as an alternative, this equivalent function (macro) can be used:
 * #define lerp(a0, a1, w) ((a0) + (w)*((a1) - (a0))) 
 */
float lerp(float a0, float a1, float w) {
    return (1.0f - w)*a0 + w*a1;
}

// Computes the dot product of the distance and gradient vectors.
float dotGridGradient(int ix, int iy, float x, float y) {

    // Precomputed (or otherwise) gradient vectors at each grid node
    extern float Gradient[IYMAX][IXMAX][2];

    // Compute the distance vector
    float dx = x - (float)ix;
    float dy = y - (float)iy;

    // Compute the dot-product
    return (dx*Gradient[iy][ix][0] + dy*Gradient[iy][ix][1]);
}

// Compute Perlin noise at coordinates x, y
float perlin(float x, float y) {

    // Determine grid cell coordinates
    int x0 = (int)x;
    int x1 = x0 + 1;
    int y0 = (int)y;
    int y1 = y0 + 1;

    // Determine interpolation weights
    // Could also use higher order polynomial/s-curve here
    float sx = x - (float)x0;
    float sy = y - (float)y0;

    // Interpolate between grid point gradients
    float n0, n1, ix0, ix1, value;

    n0 = dotGridGradient(x0, y0, x, y);
    n1 = dotGridGradient(x1, y0, x, y);
    ix0 = lerp(n0, n1, sx);

    n0 = dotGridGradient(x0, y1, x, y);
    n1 = dotGridGradient(x1, y1, x, y);
    ix1 = lerp(n0, n1, sx);

    value = lerp(ix0, ix1, sy);
    return value;
}

Complexity

For each evaluation of the noise function, the dot product of the position and gradient vectors must be evaluated at each node of the containing grid cell. Perlin noise therefore scales with complexity for dimensions. Alternatives to Perlin noise producing similar results with improved complexity scaling include simplex noise and OpenSimplex noise.

gollark: What would you want included then? Node, skynet, the PotatOS screensavers…?
gollark: I guess what you'd want is just a collection of programs/libraries plus autoupdate?
gollark: That's 90% of the features gone.
gollark: When I'm actually at my computer I mean.
gollark: If it helps at all, I can toggle on simplified uninstall or something …

See also

References

  1. Perlin, Ken. "Making Noise". noisemachine.com. Ken Perlin. Archived from the original on October 8, 2007.
  2. Perlin, Ken (July 1985). "An Image Synthesizer". SIGGRAPH Comput. Graph. 19 (97–8930): 287–296. doi:10.1145/325165.325247.
  3. Original source code Archived 2018-05-01 at the Wayback Machine of Ken Perlin's 'coherent noise function'
  4. Gustavson, Stefan. "Simplex noise demystified" (PDF). Retrieved 24 April 2019.
  5. US patent 6867776, Kenneth Perlin, "Standard for perlin noise", issued 2005-03-15, assigned to Kenneth Perlin and Wsou Investments LLC
  6. Kerman, Phillip. Macromedia Flash 8 @work: Projects and Techniques to Get the Job Done. Sams Publishing. 2006. ISBN 9780672328282.
  7. Gustavson, Stefan. "Simplex noise demystified" (PDF). Retrieved 24 April 2019.
  8. "libnoise". Archived from the original on 2018-05-13. Retrieved 2014-09-22.
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.