Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
69 lines (42 sloc) 3.14 KB

noise

This module implements a three-dimensional coherent noise generator using the Simplex method of Ken Perlin, as described in Real-Time Shading SIGGRAPH Course Notes (2001), Chapter 2: Noise Hardware. The output is deterministic, but infinite and non-repeating in all directions.

API

  • double noise_sample(double x, double y, double z)

    Sample the noise function at the point (x, y, z). The output is in the range −1 to +1, though this bound is extremely loose.

  • void noise_buffer(double x, double y, double z, double f, int w, int h, double *v)

    Generate a monochrome image of coherent noise by sampling the noise function along the Z plane. The point (x, y, z) gives the 3D position of the origin of the 2D sampling. The argument f gives a frequency coefficient, where a frequency of one maps the width and height of the buffer onto a 1×1 area of the noise function.

The argument v points to the output buffer, and w and h give the width and height of that buffer. After sampling, the values in the output buffer are normalized to the exact range −1 to +1.

Examples

Coherent noise is usually sampled in several harmonics. Here, assume p1 through p7 are n×n buffers. We fill each with a block of coherent noise, sampled at (0.0, 0.0, 0.5).

noise_buffer(0.0, 0.0, 0.5,   2.0, n, n, p1);
noise_buffer(0.0, 0.0, 0.5,   4.0, n, n, p2);
noise_buffer(0.0, 0.0, 0.5,   8.0, n, n, p3);
noise_buffer(0.0, 0.0, 0.5,  16.0, n, n, p4);
noise_buffer(0.0, 0.0, 0.5,  32.0, n, n, p5);
noise_buffer(0.0, 0.0, 0.5,  64.0, n, n, p6);
noise_buffer(0.0, 0.0, 0.5, 128.0, n, n, p7);

Different effects can be achieved through different combinations of these harmonics. For example, the basic 1/f noise divides the contribution of each harmonic by its frequency. The sum 1/2 + 1/4 + 1/8 + … approaches 1 in the limit, so the range of the sum approaches the range of an individual harmonic in the limit. The output in the range −1 to +1 is normalized to the range 0 to 1.

for (i = 0; i < n * n; ++i)

    p[i] = (1.0 + p1[i] /   2.0
                + p2[i] /   4.0
                + p3[i] /   8.0
                + p4[i] /  16.0
                + p5[i] /  32.0
                + p6[i] /  64.0
                + p7[i] / 128.0) / 2.0;

Here is that result:

The "plasma" effect is achieved by taking the absolute value of each harmonic.

for (i = 0; i < n * n; ++i)

    p[i] = (1.0 + fabs(p1[i]) /   2.0
                + fabs(p2[i]) /   4.0
                + fabs(p3[i]) /   8.0
                + fabs(p4[i]) /  16.0
                + fabs(p5[i]) /  32.0
                + fabs(p6[i]) /  64.0
                + fabs(p7[i]) / 128.0) / 2.0;

Here is that result:

For more examples and discussion, see Perlin's noise course notes.