Procedural noise functions return smoothly varying results as calculated from spatial coordinates (as the spatial coordinate changes so does the value). The derivatives of procedural noise functions can be useful in many different ways.
eg
– analytical bump/normal mapping
– interesting fractal effects
– calculating entirely new noise types
Noise derivatives can be calculated in a number of ways. Ken Perlin gives an example where derivatives are calculated numerically using finite differencing (5.6). An advantage to this is the noise function can be any arbitrarily complex function. Disadvantages are that the noise function needs sampling 3 times and some fixed epsilon value needs to be chosen (eg 0.0001). Hugh Malan shows that for realtime use derivatives can be baked into a texture along with the original value (20.3.1). Although very efficient the disadvantage with this is we’re now locked into a fixed resolution which makes general use problematic. Morten Mikkelsen shows that GPU hardware derivative units can be used, which is a very nice and efficient solution, but the result suffers from grainy artifacts due to the 2×2 sampling strategy used by derivative hardware.
Another approach is to calculate the derivatives analytically. That is, the procedural noise function calculates both the result and the derivative mathematically in a single call. This has the advantage of only needing to be called once and also being robust when sampled at any scale.
Given the advantages/uses of procedural noise derivatives I’m surprised analytical derivatives have not received much attention at all. I went hunting and found Stefan Gustavson’s work on simplex noise derivatives in C++, Giliam de Carpentier’s work on 2D Perlin noise derivatives and Milo Yip’s post regarding 3D perlin noise derivatives. With that I went about implementing them myself. As a result the noise library now contains common noise functions (value, perlin, cellular, hermite and simplex) which also return analytical derivatives.
Here are some screenshots showing some common procedural noise functions with their corresponding derivatives. Please note that all images have been normalized to a 0.0->1.0 range for ease of viewing. In reality the noise values range from -1.0->1.0 and noise derivatives can have any range but generally somewhere around -3.0->3.0