ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/noise3.c
Revision: 1.6
Committed: Fri Aug 2 13:57:09 1991 UTC (32 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +3 -2 lines
Log Message:
minor changes

File Contents

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