sources:


website:
more info here


screenshot:
studies/grafik2/Computergrafik-Code9/Aufgabe25/noise.cpp
download file

  1 /*-------------------------------------------------------------------- noise function over R3 - implemented by a pseudorandom tricubic spline EXCERPTED FROM SIGGRAPH 92, COURSE 23 PROCEDURAL MODELING Ken Perlin New York University ----------------------------------------------------------------------*/
  2
  3 #include "noise.h"
  4 #include <stdlib.h>
  5
  6 #define B 256
  7 static int p[B + B + 2];
  8 static float g[B + B + 2][3];
  9
 10 #define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
 11 #define setup(i,b0,b1,r0,r1) \
 12         t = vec[i] + 10000.; ===>\<===
 13         b0 = ((int)t) & (B-1); ===>\<===
 14         b1 = (b0+1) & (B-1); ===>\<===
 15         r0 = t - (int)t; ===>\<===
 16         r1 = r0 - 1.;
 17
 18
 19 void Noise::init() {
 20         /*long random();*/
 21         int i, j, k;
 22         float v[3], s;
 23
 24 /* Create an array of random gradient vectors uniformly on the unit sphere */
 25         /*srandom(1);*/
 26         srand(1);
 27         for (i = 0 ; i < B ; i++) {
 28                 do {                            /* Choose uniformly in a cube */                        for (j=0 ; j<3 ; j++)
 29                                 v[j] = (float)((rand() % (B + B)) - B) / B;
 30                         s = DOT(v,v);
 31                 } while (s > 1.0);              /* If not in sphere try again */                s = sqrt(s);
 32                 for (j = 0 ; j < 3 ; j++)       /* Else normalize */
 33                         g[i][j] = v[j] / s;
 34         }
 35
 36 /* Create a pseudorandom permutation of [1..B] */
 37         for (i = 0 ; i < B ; i++)
 38                 p[i] = i;
 39         for (i = B ; i > 0 ; i -= 2) {
 40                 k = p[i];
 41                 p[i] = p[j = rand() % B];
 42                 p[j] = k;
 43         }
 44
 45 /* Extend g and p arrays to allow for faster indexing */
 46         for (i = 0 ; i < B + 2 ; i++) {
 47                 p[B + i] = p[i];
 48                 for (j = 0 ; j < 3 ; j++)
 49                         g[B + i][j] = g[i][j];
 50         }
 51 }
 52
 53 float Noise::turbulence(float point[3], float lofreq, float hifreq) {
 54         float freq, t, p[3];
 55
 56         p[0] = point[0] + 123.456;
 57         p[1] = point[1];
 58         p[2] = point[2];
 59
 60         t = 0;
 61         for (freq = lofreq ; freq < hifreq ; freq *= 2.) {
 62                 t += fabs(noise3(p)) / freq;
 63                 p[0] *= 2.;
 64                 p[1] *= 2.;
 65                 p[2] *= 2.;
 66         }
 67         return t - 0.3; /* readjust to make mean value = 0.0 */
 68 }
 69
 70 float Noise::noise3(float vec[3]) {
 71         int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
 72         float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v;
 73         register int i, j;
 74
 75         setup(0, bx0,bx1, rx0,rx1);
 76         setup(1, by0,by1, ry0,ry1);
 77         setup(2, bz0,bz1, rz0,rz1);
 78
 79         i = p[ bx0 ];
 80         j = p[ bx1 ];
 81
 82         b00 = p[ i + by0 ];
 83         b10 = p[ j + by0 ];
 84         b01 = p[ i + by1 ];
 85         b11 = p[ j + by1 ];
 86
 87 #define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
 88 #define surve(t) ( t * t * (3. - 2. * t) )
 89 #define lerp(t, a, b) ( a + t * (b - a) )
 90
 91         sx = surve(rx0);
 92         sy = surve(ry0);
 93         sz = surve(rz0);
 94
 95         q = g[ b00 + bz0 ] ; u = at(rx0,ry0,rz0);
 96         q = g[ b10 + bz0 ] ; v = at(rx1,ry0,rz0);
 97         a = lerp(sx, u, v);
 98
 99         q = g[ b01 + bz0 ] ; u = at(rx0,ry1,rz0);
100         q = g[ b11 + bz0 ] ; v = at(rx1,ry1,rz0);
101         b = lerp(sx, u, v);
102
103         c = lerp(sy, a, b);          /* interpolate in y at lo x */
104
105         q = g[ b00 + bz1 ] ; u = at(rx0,ry0,rz1);
106         q = g[ b10 + bz1 ] ; v = at(rx1,ry0,rz1);
107         a = lerp(sx, u, v);
108
109         q = g[ b01 + bz1 ] ; u = at(rx0,ry1,rz1);
110         q = g[ b11 + bz1 ] ; v = at(rx1,ry1,rz1);
111         b = lerp(sx, u, v);
112
113         d = lerp(sy, a, b);          /* interpolate in y at hi x */
114
115         return 1.5 * lerp(sz, c, d); /* interpolate in z */
116 }
117
118
119