ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/noise3.c
Revision: 2.7
Committed: Tue Feb 25 02:47:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.6: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.6 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4     /*
5     * noise3.c - noise functions for random textures.
6     *
7     * Credit for the smooth algorithm goes to Ken Perlin.
8     * (ref. SIGGRAPH Vol 19, No 3, pp 287-96)
9 greg 2.6 */
10    
11 greg 2.7 #include "copyright.h"
12 greg 1.1
13 greg 2.2 #include <math.h>
14 greg 1.1
15     #define A 0
16     #define B 1
17     #define C 2
18     #define D 3
19    
20     #define rand3a(x,y,z) frand(67*(x)+59*(y)+71*(z))
21     #define rand3b(x,y,z) frand(73*(x)+79*(y)+83*(z))
22     #define rand3c(x,y,z) frand(89*(x)+97*(y)+101*(z))
23     #define rand3d(x,y,z) frand(103*(x)+107*(y)+109*(z))
24    
25 greg 1.7 #define hpoly1(t) ((2.0*t-3.0)*t*t+1.0)
26     #define hpoly2(t) (-2.0*t+3.0)*t*t
27     #define hpoly3(t) ((t-2.0)*t+1.0)*t
28     #define hpoly4(t) (t-1.0)*t*t
29 greg 1.1
30 greg 1.7 #define hermite(p0,p1,r0,r1,t) ( p0*hpoly1(t) + \
31     p1*hpoly2(t) + \
32     r0*hpoly3(t) + \
33     r1*hpoly4(t) )
34    
35 greg 2.5 static char noise_name[4][8] = {"noise3x", "noise3y", "noise3z", "noise3"};
36 greg 1.5 static char fnoise_name[] = "fnoise3";
37     static char hermite_name[] = "hermite";
38 greg 1.1
39 greg 1.5 double *noise3(), fnoise3(), argument(), frand();
40 greg 2.3 static interpolate();
41 greg 1.5
42 greg 1.1 static long xlim[3][2];
43     static double xarg[3];
44    
45 greg 2.4 #define EPSILON .001 /* error allowed in fractal */
46 greg 1.1
47 greg 1.3 #define frand3(x,y,z) frand(17*(x)+23*(y)+29*(z))
48 greg 1.1
49    
50 greg 1.5 static double
51     l_noise3(nam) /* compute a noise function */
52     register char *nam;
53 greg 1.1 {
54 greg 1.5 register int i;
55     double x[3];
56     /* get point */
57     x[0] = argument(1);
58     x[1] = argument(2);
59     x[2] = argument(3);
60     /* make appropriate call */
61     if (nam == fnoise_name)
62     return(fnoise3(x));
63     i = 4;
64     while (i--)
65     if (nam == noise_name[i])
66     return(noise3(x)[i]);
67 greg 1.6 eputs(nam);
68     eputs(": called l_noise3!\n");
69 greg 1.5 quit(1);
70 greg 1.1 }
71    
72    
73     double
74 greg 1.5 l_hermite() /* library call for hermite interpolation */
75 greg 1.1 {
76 greg 1.5 double t;
77    
78     t = argument(5);
79     return( hermite(argument(1), argument(2),
80     argument(3), argument(4), t) );
81 greg 1.1 }
82    
83    
84 greg 1.5 setnoisefuncs() /* add noise functions to library */
85 greg 1.1 {
86 greg 1.5 register int i;
87 greg 1.1
88 greg 1.5 funset(hermite_name, 5, ':', l_hermite);
89     funset(fnoise_name, 3, ':', l_noise3);
90     i = 4;
91     while (i--)
92     funset(noise_name[i], 3, ':', l_noise3);
93 greg 1.1 }
94    
95    
96     double *
97     noise3(xnew) /* compute the noise function */
98     register double xnew[3];
99     {
100     static double x[3] = {-100000.0, -100000.0, -100000.0};
101     static double f[4];
102    
103     if (x[0]==xnew[0] && x[1]==xnew[1] && x[2]==xnew[2])
104     return(f);
105     x[0] = xnew[0]; x[1] = xnew[1]; x[2] = xnew[2];
106     xlim[0][0] = floor(x[0]); xlim[0][1] = xlim[0][0] + 1;
107     xlim[1][0] = floor(x[1]); xlim[1][1] = xlim[1][0] + 1;
108     xlim[2][0] = floor(x[2]); xlim[2][1] = xlim[2][0] + 1;
109     xarg[0] = x[0] - xlim[0][0];
110     xarg[1] = x[1] - xlim[1][0];
111     xarg[2] = x[2] - xlim[2][0];
112     interpolate(f, 0, 3);
113     return(f);
114     }
115    
116    
117     static
118     interpolate(f, i, n)
119     double f[4];
120     register int i, n;
121     {
122 greg 1.7 double f0[4], f1[4], hp1, hp2;
123 greg 1.1
124     if (n == 0) {
125     f[A] = rand3a(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
126     f[B] = rand3b(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
127     f[C] = rand3c(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
128     f[D] = rand3d(xlim[0][i&1],xlim[1][i>>1&1],xlim[2][i>>2]);
129     } else {
130     n--;
131     interpolate(f0, i, n);
132     interpolate(f1, i | 1<<n, n);
133 greg 1.7 hp1 = hpoly1(xarg[n]); hp2 = hpoly2(xarg[n]);
134     f[A] = f0[A]*hp1 + f1[A]*hp2;
135     f[B] = f0[B]*hp1 + f1[B]*hp2;
136     f[C] = f0[C]*hp1 + f1[C]*hp2;
137     f[D] = f0[D]*hp1 + f1[D]*hp2 +
138     f0[n]*hpoly3(xarg[n]) + f1[n]*hpoly4(xarg[n]);
139 greg 1.1 }
140     }
141    
142    
143     double
144     frand(s) /* get random number from seed */
145     register long s;
146     {
147     s = s<<13 ^ s;
148     return(1.0-((s*(s*s*15731+789221)+1376312589)&0x7fffffff)/1073741824.0);
149     }
150    
151    
152     double
153     fnoise3(p) /* compute fractal noise function */
154 greg 1.3 double p[3];
155 greg 1.1 {
156 greg 1.4 long t[3], v[3], beg[3];
157 greg 1.3 double fval[8], fc;
158     int branch;
159 greg 1.4 register long s;
160 greg 1.1 register int i, j;
161     /* get starting cube */
162 greg 1.3 s = (long)(1.0/EPSILON);
163     for (i = 0; i < 3; i++) {
164     t[i] = s*p[i];
165     beg[i] = s*floor(p[i]);
166     }
167 greg 1.1 for (j = 0; j < 8; j++) {
168     for (i = 0; i < 3; i++) {
169     v[i] = beg[i];
170     if (j & 1<<i)
171 greg 1.3 v[i] += s;
172 greg 1.1 }
173     fval[j] = frand3(v[0],v[1],v[2]);
174     }
175     /* compute fractal */
176     for ( ; ; ) {
177 greg 1.4 fc = 0.0;
178     for (j = 0; j < 8; j++)
179     fc += fval[j];
180     fc *= 0.125;
181     if ((s >>= 1) == 0)
182     return(fc); /* close enough */
183 greg 1.1 branch = 0;
184     for (i = 0; i < 3; i++) { /* do center */
185     v[i] = beg[i] + s;
186 greg 1.3 if (t[i] > v[i]) {
187 greg 1.1 branch |= 1<<i;
188 greg 1.3 }
189 greg 1.1 }
190 greg 1.3 fc += s*EPSILON*frand3(v[0],v[1],v[2]);
191 greg 1.1 fval[~branch & 7] = fc;
192     for (i = 0; i < 3; i++) { /* do faces */
193     if (branch & 1<<i)
194     v[i] += s;
195     else
196     v[i] -= s;
197     fc = 0.0;
198     for (j = 0; j < 8; j++)
199     if (~(j^branch) & 1<<i)
200     fc += fval[j];
201 greg 1.3 fc = 0.25*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
202 greg 1.1 fval[~(branch^1<<i) & 7] = fc;
203     v[i] = beg[i] + s;
204     }
205     for (i = 0; i < 3; i++) { /* do edges */
206     j = (i+1)%3;
207     if (branch & 1<<j)
208     v[j] += s;
209     else
210     v[j] -= s;
211     j = (i+2)%3;
212     if (branch & 1<<j)
213     v[j] += s;
214     else
215     v[j] -= s;
216     fc = fval[branch & ~(1<<i)];
217     fc += fval[branch | 1<<i];
218 greg 1.3 fc = 0.5*fc + s*EPSILON*frand3(v[0],v[1],v[2]);
219 greg 1.1 fval[branch^1<<i] = fc;
220     j = (i+1)%3;
221     v[j] = beg[j] + s;
222     j = (i+2)%3;
223     v[j] = beg[j] + s;
224     }
225     for (i = 0; i < 3; i++) /* new cube */
226     if (branch & 1<<i)
227     beg[i] += s;
228     }
229     }