i
i
i
i
i
i
i
i
248 11. Texture Mapping
by using a sort of “solid noise,” usually called Perlin noise after its inventor, who
received a technical Academy Award for its impact in the film industry (Perlin,
1985).
Getting a noisy appearance by calling a random number for every point would
not be appropriate, because it would just be like “white noise” in TV static. We
would like to make it smoother without losing the random quality. One possibility
is to blur white noise, but there is no practical implementation of this. Another
possibility is to make a large lattice with a random number at every lattice point,
and then interpolate these random points for new points between lattice nodes;
this is just a 3D texture array as described in the last section with random numbers
in the array. This technique makes the lattice too obvious. Perlin used a variety
of tricks to improve this basic lattice technique so the lattice was not so obvious.
This results in a rather baroque-looking set of steps, but essentially there are just
three changes from linearly interpolating a 3D array of random values. The first
change is to use Hermite interpolation to avoid mach bands, just as can be done
with regular textures. The second change is the use of random vectors rather than
values, with a dot product to derive a random number; this makes the underlying
grid structure less visually obvious by moving the local minima and maxima off
the grid vertices. The third change is to use a 1D array and hashing to create a
virtual 3D array of random vectors. This adds computation to lower memory use.
Here is his basic method:
n(x, y, z)=
x+1
i=x
y+1
j=y
z+1
k=z
Ω
ijk
(x − i, y −j, z − k),
where (x, y, z) are the Cartesian coordinates of x,and
Ω
ijk
(u, v, w)=ω(u)ω(v)ω(w)(Γ
ijk
· (u, v, w)) ,
and ω(t) is the cubic weighting function:
ω(t)=
2|t|
3
− 3|t|
2
+1 if |t| < 1,
0 otherwise.
Figure 11.4. Absolute
value of solid noise, and
noise for scaled
x
and
y
val-
ues.
The final piece is that Γ
ijk
is a random unit vector for the lattice point(x, y, z)=
(i, j, k). Since we want any potential ijk, we use a pseudorandom table:
Γ
ijk
= G (φ(i + φ(j + φ(k)))) ,
where G is a precomputed array of n random unit vectors, and φ(i)=
P [i mod n] where P is an array of length n containing a permutation of the