1 /* OpenSceneGraph example, osgshaders.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16 * THE SOFTWARE.
17 */
18
19 /************************************************************************
20 * *
21 * Copyright (C) 2002 3Dlabs Inc. Ltd. *
22 * *
23 ************************************************************************/
24
25 #include <math.h>
26 #include <stdlib.h>
27
28 /* Coherent noise function over 1, 2 or 3 dimensions */
29 /* (copyright Ken Perlin) */
30
31 #define MAXB 0x100
32 #define N 0x1000
33 #define NP 12 /* 2^N */
34 #define NM 0xfff
35
36 #define s_curve(t) ( t * t * (3. - 2. * t) )
37 #define lerp(t, a, b) ( a + t * (b - a) )
38 #define setup(i,b0,b1,r0,r1)\
39 t = vec[i] + N;\
40 b0 = ((int)t) & BM;\
41 b1 = (b0+1) & BM;\
42 r0 = t - (int)t;\
43 r1 = r0 - 1.;
44 #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
45 #define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
46
47 static void initNoise(void);
48
49 static int p[MAXB + MAXB + 2];
50 static double g3[MAXB + MAXB + 2][3];
51 static double g2[MAXB + MAXB + 2][2];
52 static double g1[MAXB + MAXB + 2];
53
54 int start;
55 int B;
56 int BM;
57
58
SetNoiseFrequency(int frequency)59 void SetNoiseFrequency(int frequency)
60 {
61 start = 1;
62 B = frequency;
63 BM = B-1;
64 }
65
noise1(double arg)66 double noise1(double arg)
67 {
68 int bx0, bx1;
69 double rx0, rx1, sx, t, u, v, vec[1];
70
71 vec[0] = arg;
72 if (start) {
73 start = 0;
74 initNoise();
75 }
76
77 setup(0,bx0,bx1,rx0,rx1);
78
79 sx = s_curve(rx0);
80 u = rx0 * g1[ p[ bx0 ] ];
81 v = rx1 * g1[ p[ bx1 ] ];
82
83 return(lerp(sx, u, v));
84 }
85
noise2(double vec[2])86 double noise2(double vec[2])
87 {
88 int bx0, bx1, by0, by1, b00, b10, b01, b11;
89 double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
90 int i, j;
91
92 if (start) {
93 start = 0;
94 initNoise();
95 }
96
97 setup(0, bx0,bx1, rx0,rx1);
98 setup(1, by0,by1, ry0,ry1);
99
100 i = p[ bx0 ];
101 j = p[ bx1 ];
102
103 b00 = p[ i + by0 ];
104 b10 = p[ j + by0 ];
105 b01 = p[ i + by1 ];
106 b11 = p[ j + by1 ];
107
108 sx = s_curve(rx0);
109 sy = s_curve(ry0);
110
111 q = g2[ b00 ] ; u = at2(rx0,ry0);
112 q = g2[ b10 ] ; v = at2(rx1,ry0);
113 a = lerp(sx, u, v);
114
115 q = g2[ b01 ] ; u = at2(rx0,ry1);
116 q = g2[ b11 ] ; v = at2(rx1,ry1);
117 b = lerp(sx, u, v);
118
119 return lerp(sy, a, b);
120 }
121
noise3(double vec[3])122 double noise3(double vec[3])
123 {
124 int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
125 double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
126 int i, j;
127
128 if (start) {
129 start = 0;
130 initNoise();
131 }
132
133 setup(0, bx0,bx1, rx0,rx1);
134 setup(1, by0,by1, ry0,ry1);
135 setup(2, bz0,bz1, rz0,rz1);
136
137 i = p[ bx0 ];
138 j = p[ bx1 ];
139
140 b00 = p[ i + by0 ];
141 b10 = p[ j + by0 ];
142 b01 = p[ i + by1 ];
143 b11 = p[ j + by1 ];
144
145 t = s_curve(rx0);
146 sy = s_curve(ry0);
147 sz = s_curve(rz0);
148
149 q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
150 q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
151 a = lerp(t, u, v);
152
153 q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
154 q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
155 b = lerp(t, u, v);
156
157 c = lerp(sy, a, b);
158
159 q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
160 q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
161 a = lerp(t, u, v);
162
163 q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
164 q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
165 b = lerp(t, u, v);
166
167 d = lerp(sy, a, b);
168
169 //fprintf(stderr, "%f\n", lerp(sz, c, d));
170
171 return lerp(sz, c, d);
172 }
173
normalize2(double v[2])174 void normalize2(double v[2])
175 {
176 double s;
177
178 s = sqrt(v[0] * v[0] + v[1] * v[1]);
179 v[0] = v[0] / s;
180 v[1] = v[1] / s;
181 }
182
normalize3(double v[3])183 void normalize3(double v[3])
184 {
185 double s;
186
187 s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
188 v[0] = v[0] / s;
189 v[1] = v[1] / s;
190 v[2] = v[2] / s;
191 }
192
initNoise(void)193 void initNoise(void)
194 {
195 int i, j, k;
196
197 srand(30757);
198 for (i = 0 ; i < B ; i++) {
199 p[i] = i;
200 g1[i] = (double)((rand() % (B + B)) - B) / B;
201
202 for (j = 0 ; j < 2 ; j++)
203 g2[i][j] = (double)((rand() % (B + B)) - B) / B;
204 normalize2(g2[i]);
205
206 for (j = 0 ; j < 3 ; j++)
207 g3[i][j] = (double)((rand() % (B + B)) - B) / B;
208 normalize3(g3[i]);
209 }
210
211 while (--i) {
212 k = p[i];
213 p[i] = p[j = rand() % B];
214 p[j] = k;
215 }
216
217 for (i = 0 ; i < B + 2 ; i++) {
218 p[B + i] = p[i];
219 g1[B + i] = g1[i];
220 for (j = 0 ; j < 2 ; j++)
221 g2[B + i][j] = g2[i][j];
222 for (j = 0 ; j < 3 ; j++)
223 g3[B + i][j] = g3[i][j];
224 }
225 }
226
227 /* --- My harmonic summing functions - PDB --------------------------*/
228
229 /*
230 In what follows "alpha" is the weight when the sum is formed.
231 Typically it is 2, As this approaches 1 the function is noisier.
232 "beta" is the harmonic scaling/spacing, typically 2.
233 */
234
PerlinNoise1D(double x,double alpha,double beta,int n)235 double PerlinNoise1D(double x,double alpha,double beta,int n)
236 {
237 int i;
238 double val,sum = 0;
239 double p,scale = 1;
240
241 p = x;
242 for (i=0;i<n;i++) {
243 val = noise1(p);
244 sum += val / scale;
245 scale *= alpha;
246 p *= beta;
247 }
248 return(sum);
249 }
250
PerlinNoise2D(double x,double y,double alpha,double beta,int n)251 double PerlinNoise2D(double x,double y,double alpha,double beta,int n)
252 {
253 int i;
254 double val,sum = 0;
255 double p[2],scale = 1;
256
257 p[0] = x;
258 p[1] = y;
259 for (i=0;i<n;i++) {
260 val = noise2(p);
261 sum += val / scale;
262 scale *= alpha;
263 p[0] *= beta;
264 p[1] *= beta;
265 }
266 return(sum);
267 }
268
PerlinNoise3D(double x,double y,double z,double alpha,double beta,int n)269 double PerlinNoise3D(double x,double y,double z,double alpha,double beta,int n)
270 {
271 int i;
272 double val,sum = 0;
273 double p[3],scale = 1;
274
275 p[0] = x;
276 p[1] = y;
277 p[2] = z;
278 for (i=0;i<n;i++) {
279 val = noise3(p);
280 sum += val / scale;
281 scale *= alpha;
282 p[0] *= beta;
283 p[1] *= beta;
284 p[2] *= beta;
285 }
286 return(sum);
287 }
288