root/OpenSceneGraph/trunk/examples/osgshaders/Noise.cpp @ 6941

Revision 6941, 6.3 kB (checked in by robert, 8 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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
47static void initNoise(void);
48
49static int p[MAXB + MAXB + 2];
50static double g3[MAXB + MAXB + 2][3];
51static double g2[MAXB + MAXB + 2][2];
52static double g1[MAXB + MAXB + 2];
53
54int start;
55int B;
56int BM;
57
58
59void SetNoiseFrequency(int frequency)
60{
61        start = 1;
62        B = frequency;
63        BM = B-1;
64}
65
66double 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
86double 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
122double 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
174void 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
183void 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
193void 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
235double 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
251double 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
269double 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}
Note: See TracBrowser for help on using the browser.