Stub for Perlin-like and value noise.
This family of noise functions are incredibly useful tools for creating and modifing content. According to CG industry lore it was informally observed in the 90s that "90% of 3D rendering time is spent in shading, and 90% of that time is spent computing Perlin (gradient) noise". Regardless of the truth of this observation, this family of noise functions are certainly one of the most important techiques not only in proceeduarally generated content but in CG as a whole. Increases in CPU speed and the relatively new addition of GPU computation allow for runtime evaluation of the cheaper of these methods in realtime graphics.
Attempting to give any detailed descriptions of how to "use" noise functions to create or modify content is well beyond the scope of any short description. The goal here is to outline some basics of core generation techniques and to provide links to more detailed information in specific areas of interest.
For the local discussion, we'll assume that noise accepts floating point input for a sample coordinate and returns a floating point value (usually either on [0,1] or [-1,1]). It will provide some sketches of 2D implementations to (hopefully) aid in understanding.
Noise functions are evaluated in some number of dimensions (typcially 1,2,3 or 4). This is simply to say that you provide some input coordinate and noise returns the corresponding fixed value at that position, just like any other multi-dimensional function. From a signal processing perspective this family can be described as an attempt to approximate band-pass filtering
of white noise
. Perhaps a simplier description would be that they are attempts at coherent pseudo-random number generators (PRNG).
Regular PRNGs attempt to create a fixed sequence (from some initial state data...frequently termed the 'seed') of values that appear to be statistically independent. White noise can be created from a PRNG as in the following sketch (in 2D):
float eval(float x, float y)
long seed = mix(x,y); prng.setSeed(seed); return prng.nextFloat(); }
Unfortuately raw white noise is of very little use. If you were to create a 2D texture from white noise, regardless of how you walk through the 'noise' function the result would be virtually identical. The result would be like what you'd see on an old broadcast TV tuned to a channel without a signal. What's really needed to be useful are random values that are coherent: which roughly says that sample points far apart are like PRNG values, appear to be independent, and the set of all sample points close to one another vary continously (or smoothly in less formal speak).
Value noiseValue noise
is the one of the original attempts at this style of noise generation. It is very often miscalled Perlin noise. Evaluation is very cheap, but it burden with serious defects and is very poor at band-pass filtering. Quality can be improved, but even the most basic improvements make it more expensive than gradient noise. So a general guidline for using this techique is to only use a very cheap version and only when some exisiting content can be minorly modified by one or two evaluations.
Value noise is computed by forming a regular grid, computing random values at each vertex and blending the values to produce a result. Sketch in 2D:
float eval(float x, float y)
int ix = (int)Math.floor(x);
int iy = (int)Math.floor(y);
float dx = x - ix;
float dy = y - iy;
float r00 = mix(ix, iy);
float r10 = mix(ix+1, iy);
float r01 = mix(ix, iy+1);
float r11 = mix(ix+1, iy+1);
So to compute value noise in 'n' dimensions, the work required is related to n2
(1D = line segement or 2 vertices, 2D = square or 4 verts, 3D = cube and 8, etc). The problems with value noise stem from the fact that at each evaluation point, the result only depends on blended data interior the cell that its within. This results in sample points close to one another, but in different cells, to not vary continously. This results in very obvious defects along cell boundaries. Early attempts to fix this major problem included visting further away cells and using more complex blending functions...which drastically increase complexity. The introduction of gradient noise made these solutions obsolete.References
Perlin gradient noise
Created in 1983 by Ken Perlin, this Oscar award winning technqiue is a clever way to minorly modify value noise to drastically improve the output quality. Usually when one is (correctly) calling a noise function "Perlin" noise, this is the techique being discussed. The clever addition is to choose a vector associated with each vertex (gradient vector). Then to calculate the vector from the vertex to the sample point. The dot product between these two vectors gives the influence of random value on the output of the sample point. BLAH, BLAH...
Note that there have been numerious improvements made to gradient noise over the years, so some references may be refering to older versions. And, of course, authors may make minor tweaks (for better or worse) to their specific implemenation.
Variants of note:
- Originally the vectors were randomly generated unit vectors. Perlin later noted that using a small set of vectors (all the permutations of vector components of zero or one) drastically reduced computational cost.
- Two ease functions - note difference
Yeah...add tons of stuff here
Perlin simplex noise
In 2002 Ken Perlin...blah blahReferences
There are many other noise functions, must of which are too complex to be evaluated at runtime, but may have game usage for pre-generated content. BLAH BLAH:
- Anisotropic noise
- Gabor noise: not the same family, but can generate similar results.
- Sparse convolution noise
- Wavelet noise
This wiki entry has had 21 revisions with contributions from 2 members.