Using Noise

This document gives a short introduction to Ken Perlin's (Technical Academy Award-winning) noise function. Perlin Noise is used ubiquitously in procedural shaders written in the film production and special effects industries.


Properties

There are three important properties of noise: The following plot shows a trace of noise in 1d.

Compared to using something like a sine curve to perturb a value based on spatial location, this has the advantage of random variation. Compared to calling random(), this has the advantage of being continuous. Note that noise has the value of zero at all integer x locations; in three-d, it is zero whenever all of (x,y,z) are integers.


Adding together multiple scales

One scale of noise (as in the graph above) is often not enough; adding together more scales of noise can give finer variation. A common way of doing this is with a function like the FBm() function that we provide in mnoise.h; this is its operation in pseudocode:

float FBm(Point P, float omega, float lambda, int octaves)
{
  float value = 0.;
  float o = 1.;
  float l = 1.;

  for (int i = 0; i < octaves; ++i)
  {
    value += o * noise(l * P);
    o *= omega;
    l *= lambda;
  }

  return value;
}
Note how the three parameters affect the noise value returned:

Putting it to use

Ok, so you've got this nice noise value that's defined in three-space, you've tuned it to be as smooth or rough as you want, now what?

To make a rough taxonomy, there are two main ways of using noise: perturbing and indexing. Consider using it to perturb arguments to other functions. For instance, given a (u,v) texture coordinate, you could use noise to compute an offset du. Then, rather than looking up (u,v) in the texture map, you could look up (u+du, v). Or, you could compute two different noise values and offset both u and v. There's obviously a trade-off to be made between perturbing so little that you can't see any difference and perturbing so much that the result is unintelligible.

Noise can also be used to compute consistent indices for a wide variety of values. Consider a 2d checkerboard, for instance. Say that you wanted to give each check a unique color. This is a little bit tricky, since you somehow need to compute a color for each point that's shaded inside each check, and you need to come up with the same result for each point in the same check. Say that your checkerboard was defined on an integer grid, though. At each (x,y) point being shaded, you could compute a noise value using the point ((int)x+.5, (int)y+.5, 0) as input to the noise function. Thus, the same noise value will be computed for each point in the check and thus could be used to index into a color map.


CS248: Introduction to Computer Graphics, Pat Hanrahan, Fall 1998