ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/noise3.c
Revision: 1.4
Committed: Wed May 22 08:56:21 1991 UTC (32 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.3: +8 -8 lines
Log Message:
moved test in fnoise3() (optimization)

File Contents

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