Perlin noise

Last updated
Two-dimensional slice through 3D Perlin noise at z = 0 Perlin noise example.png
Two-dimensional slice through 3D Perlin noise at z = 0

Perlin noise is a type of gradient noise developed by Ken Perlin in 1983. It has many uses, including but not limited to: procedurally generating terrain, applying pseudo-random changes to a variable, and assisting in the creation of image textures. It is most commonly implemented in two, three, or four dimensions, but can be defined for any number of dimensions.

Contents

History

Ken Perlin developed Perlin noise 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] He developed it after working on Disney's computer animated sci-fi motion picture Tron (1982) for the animation company Mathematical Applications Group (MAGI). [3] In 1997, Perlin was awarded an Academy Award for Technical Achievement for creating the algorithm, the citation for which read: [4] [5] [6] [7]

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.

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. [8]

Uses

A virtual landscape generated using Perlin noise Fractal terrain texture.jpg
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 Pink red liquid using perlin noise + bump + coloring (2415197699).png
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-real-time procedural textures in all kinds of computer graphics.

It is frequently used in video games to make procedurally generated terrain that looks natural. This success is in part due to the hierarchical structuring of Perlin noise that mimics naturally occurring hierarchical structures, and therefore also has found to be useful in environmental science applications. [9]

Algorithm detail

Perlin noise rescaled and added into itself to create fractal noise. At each step, noise frequency is doubled and amplitude is halved. Perlin animation 6 octaves.gif
Perlin noise rescaled and added into itself to create fractal noise. At each step, noise frequency is doubled and amplitude is halved.
2-D Perlin noise with a contour line at zero, showing that the noise is zero at the gradient mesh intersections Perlin noise with contour.svg
2-D Perlin noise with a contour line at zero, showing that the noise is zero at the gradient mesh intersections

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: defining a grid of random gradient vectors, computing the dot product between the gradient vectors and their offsets, and interpolation between these values. [10]

Grid definition

A two-dimensional grid of gradient vectors PerlinNoiseGradientGrid.svg
A two-dimensional grid of gradient vectors

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

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. PerlinNoiseDotProducts.svg
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.

For working out the value of any candidate point, first find the unique grid cell in which the point lies. Then, identify the 2n corners of that cell and their associated gradient vectors. Next, for each corner, calculate an offset vector. An offset vector is a displacement vector from that corner to the candidate point.

For each corner, we take the dot product between its gradient vector and the offset vector to the candidate point. This dot product will be zero if the candidate point is exactly at the grid corner.

Note that a gradient vector's influence grows with distance, which can be avoided by normalizing the offset vector to a length of 1 first. This would introduce noticeable sharp changes, except the distance is taken into account in the following interpolation step. Normalizing the offset vector is however not a common practice.

For a point in a two-dimensional grid, this will require the computation of four offset vectors and dot products, while in three dimensions it will require eight offset vectors and eight dot products. In general, the algorithm has O(2n) complexity in n dimensions.

Interpolation

The final interpolated result PerlinNoiseInterpolated.svg
The final interpolated result

The final step is interpolation between the 2n dot products. Interpolation is performed using a function that has zero first derivative (and possibly also second derivative) at the 2n grid nodes. Therefore, at points close to the grid nodes, the output will approximate the dot product of the gradient vector of the node and the offset vector to the node. This means that the noise function will pass through 0 at every node, giving Perlin noise its characteristic look.

If n = 1, an example of a function that interpolates between value a0 at grid node 0 and value a1 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] and can be scaled accordingly.

Implementation

The following is a two-dimensional implementation of classical Perlin noise, written in C.

The original reference implementation by Perlin had major differences[ citation needed ]:

#include<math.h>/* Function to linearly interpolate between a0 and a1 * Weight w should be in the range [0.0, 1.0] */floatinterpolate(floata0,floata1,floatw){/* // You may want clamping by inserting:     * if (0.0 > w) return a0;     * if (1.0 < w) return a1;     */return(a1-a0)*w+a0;/* // Use this cubic interpolation [[Smoothstep]] instead, for a smooth appearance:     * return (a1 - a0) * (3.0 - w * 2.0) * w * w + a0;     *     * // Use [[Smootherstep]] for an even smoother result with a second derivative equal to zero on boundaries:     * return (a1 - a0) * ((w * (w * 6.0 - 15.0) + 10.0) * w * w * w) + a0;     */}typedefstruct{floatx,y;}vector2;/* Create pseudorandom direction vector */vector2randomGradient(intix,intiy){// No precomputed gradients mean this works for any number of grid coordinatesconstunsignedw=8*sizeof(unsigned);constunsigneds=w/2;// rotation widthunsigneda=ix,b=iy;a*=3284157443;b^=a<<s|a>>w-s;b*=1911520717;a^=b<<s|b>>w-s;a*=2048419325;floatrandom=a*(3.14159265/~(~0u>>1));// in [0, 2*Pi]vector2v;v.x=cos(random);v.y=sin(random);returnv;}// Computes the dot product of the distance and gradient vectors.floatdotGridGradient(intix,intiy,floatx,floaty){// Get gradient from integer coordinatesvector2gradient=randomGradient(ix,iy);// Compute the distance vectorfloatdx=x-(float)ix;floatdy=y-(float)iy;// Compute the dot-productreturn(dx*gradient.x+dy*gradient.y);}// Compute Perlin noise at coordinates x, yfloatperlin(floatx,floaty){// Determine grid cell coordinatesintx0=(int)floor(x);intx1=x0+1;inty0=(int)floor(y);inty1=y0+1;// Determine interpolation weights// Could also use higher order polynomial/s-curve herefloatsx=x-(float)x0;floatsy=y-(float)y0;// Interpolate between grid point gradientsfloatn0,n1,ix0,ix1,value;n0=dotGridGradient(x0,y0,x,y);n1=dotGridGradient(x1,y0,x,y);ix0=interpolate(n0,n1,sx);n0=dotGridGradient(x0,y1,x,y);n1=dotGridGradient(x1,y1,x,y);ix1=interpolate(n0,n1,sx);value=interpolate(ix0,ix1,sy);returnvalue;// Will return in range -1 to 1. To make it in range 0 to 1, multiply by 0.5 and add 0.5}

Permutation

Many implementations of Perlin noise use the same permutation set that Ken Perlin used in his original implementation. [11] That implementation is as follows:

intpermutation[]={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};

This specific permutation is not absolutely required, though it does require a randomized array of the integers 0 to 255. If creating a new permutation table, care should be taken to ensure uniform distribution of the values. [12]

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 O(2n) for n dimensions. Alternatives to Perlin noise producing similar results with improved complexity scaling include simplex noise and OpenSimplex noise.

See also

Related Research Articles

<span class="mw-page-title-main">Interpolation</span> Method for estimating new data within known data points

In the mathematical field of numerical analysis, interpolation is a type of estimation, a method of constructing (finding) new data points based on the range of a discrete set of known data points.

In numerical analysis, polynomial interpolation is the interpolation of a given bivariate data set by the polynomial of lowest possible degree that passes through the points of the dataset.

<span class="mw-page-title-main">Lagrange polynomial</span> Polynomials used for interpolation

In numerical analysis, the Lagrange interpolating polynomial is the unique polynomial of lowest degree that interpolates a given set of data.

<span class="mw-page-title-main">Bilinear interpolation</span> Method of interpolating functions on a 2D grid

In mathematics, bilinear interpolation is a method for interpolating functions of two variables using repeated linear interpolation. It is usually applied to functions sampled on a 2D rectilinear grid, though it can be generalized to functions defined on the vertices of arbitrary convex quadrilaterals.

<span class="mw-page-title-main">Cube mapping</span> Method of environment mapping in computer graphics

In computer graphics, cube mapping is a method of environment mapping that uses the six faces of a cube as the map shape. The environment is projected onto the sides of a cube and stored as six square textures, or unfolded into six regions of a single texture.

<span class="mw-page-title-main">Simplex noise</span> Construction for n-dimensional noise functions

Simplex noise is the result of an n-dimensional noise function comparable to Perlin noise but with fewer directional artifacts, in higher dimensions, and a lower computational overhead. Ken Perlin designed the algorithm in 2001 to address the limitations of his classic noise function, especially in higher dimensions.

Simulation noise is a function that creates a divergence-free vector field. This signal can be used in artistic simulations for the purposes of increasing the perception of extra detail.

In numerical analysis, multivariate interpolation is interpolation on functions of more than one variable ; when the variates are spatial coordinates, it is also known as spatial interpolation.

In the mathematical subfield numerical analysis, tricubic interpolation is a method for obtaining values at arbitrary points in 3D space of a function defined on a regular grid. The approach involves approximating the function locally by an expression of the form

In the field of mathematical analysis, an interpolation space is a space which lies "in between" two other Banach spaces. The main applications are in Sobolev spaces, where spaces of functions that have a noninteger number of derivatives are interpolated from the spaces of functions with integer number of derivatives.

<span class="mw-page-title-main">Value noise</span> Type of noise in computer graphics

Value noise is a type of noise commonly used as a procedural texture primitive in computer graphics. It is conceptually different from, and often confused with gradient noise, examples of which are Perlin noise and Simplex noise. This method consists of the creation of a lattice of points which are assigned random values. The noise function then returns the interpolated number based on the values of the surrounding lattice points.

Gradient noise is a type of noise commonly used as a procedural texture primitive in computer graphics. It is conceptually different from, and often confused with, value noise. This method consists of a creation of a lattice of random gradients, dot products of which are then interpolated to obtain values in between the lattices. An artifact of some implementations of this noise is that the returned value at the lattice points is 0. Unlike the value noise, gradient noise has more energy in the high frequencies.

Barnes interpolation, named after Stanley L. Barnes, is the interpolation of unevenly spread data points from a set of measurements of an unknown function in two dimensions into an analytic function of two variables. An example of a situation where the Barnes scheme is important is in weather forecasting where measurements are made wherever monitoring stations may be located, the positions of which are constrained by topography. Such interpolation is essential in data visualisation, e.g. in the construction of contour plots or other representations of analytic surfaces.

<span class="mw-page-title-main">Worley noise</span> Type of noise in computer graphics

Worley noise, also called Voronoi noise and cellular noise, is a noise function introduced by Steven Worley in 1996. Worley noise is an extension of the Voronoi diagram that outputs a real value at a given coordinate that corresponds to the Distance of the nth nearest seed, usually nearest seed, and the seeds are distributed evenly through the region. Worley noise is used to create procedural textures.

<span class="mw-page-title-main">OpenSimplex noise</span> N-dimensional gradient noise function

OpenSimplex noise is an n-dimensional gradient noise function that was developed in order to overcome the patent-related issues surrounding simplex noise, while likewise avoiding the visually-significant directional artifacts characteristic of Perlin noise.

This is a glossary of terms relating to computer graphics.

Noise refers to many types of random, troublesome, problematic, or unwanted signals.

Radial basis function (RBF) interpolation is an advanced method in approximation theory for constructing high-order accurate interpolants of unstructured data, possibly in high-dimensional spaces. The interpolant takes the form of a weighted sum of radial basis functions. RBF interpolation is a mesh-free method, meaning the nodes need not lie on a structured grid, and does not require the formation of a mesh. It is often spectrally accurate and stable for large numbers of nodes even in high dimensions.

In mathematics, mimetic interpolation is a method for interpolating differential forms. In contrast to other interpolation methods, which estimate a field at a location given its values on neighboring points, mimetic interpolation estimates the field's -form given the field's projection on neighboring grid elements. The grid elements can be grid points as well as cell edges or faces, depending on .

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". ACM SIGGRAPH Computer Graphics. 19 (97–8930): 287–296. doi:10.1145/325165.325247.
  3. Perlin, Ken. "In the beginning: The Pixel Stream Editor" (PDF). Retrieved May 31, 2022.
  4. Tanner, Mike. "Oscar is FX Wizard's Reward". Wired. ISSN   1059-1028 . Retrieved 2022-05-31.
  5. Original source code
  6. "Archived copy". Archived from the original on 2018-05-01. Retrieved 2011-05-29.{{cite web}}: CS1 maint: archived copy as title (link) CS1 maint: bot: original URL status unknown (link) of Ken Perlin's 'coherent noise function'
  7. Gustavson, Stefan. "Simplex noise demystified" (PDF). Archived from the original (PDF) on 21 March 2023. Retrieved 24 April 2019.
  8. USpatent 6867776,Kenneth Perlin,"Standard for perlin noise",issued 2005-03-15, assigned to Kenneth Perlinand Wsou Investments LLC
  9. Etherington, Thomas R. (2022). "Perlin noise as a hierarchical neutral landscape model". Web Ecology. 22 (1): 1–6. doi: 10.5194/we-22-1-2022 .
  10. Gustavson, Stefan. "Simplex noise demystified" (PDF). Archived from the original (PDF) on 10 March 2023. Retrieved 24 April 2019.
  11. Perlin, Ken. "Perlin noise" . Retrieved 26 August 2020.
  12. "Perlin Noise: Part 2". Archived from the original on 17 February 2023. Retrieved 26 August 2020.