ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/noise3.c
Revision: 2.5
Committed: Thu Oct 31 10:58:36 1996 UTC (28 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +1 -1 lines
Log Message:
renamed noise3{a,b,c} to noise3{x,y,z}

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