1 // noise1234
2 //
3 // Author: Stefan Gustavson, 2003-2005
4 // Contact: stefan.gustavson@liu.se
5 //
6 // This code was GPL licensed until February 2011.
7 // As the original author of this code, I hereby
8 // release it into the public domain.
9 // Please feel free to use it for whatever you want.
10 // Credit is appreciated where appropriate, and I also
11 // appreciate being told where this code finds any use,
12 // but you may do as you like.
13
14 /*
15 * This implementation is "Improved Noise" as presented by
16 * Ken Perlin at Siggraph 2002. The 3D function is a direct port
17 * of his Java reference code which was once publicly available
18 * on www.noisemachine.com (although I cleaned it up, made it
19 * faster and made the code more readable), but the 1D, 2D and
20 * 4D functions were implemented from scratch by me.
21 *
22 * This is a backport to C of my improved noise class in C++
23 * which was included in the Aqsis renderer project.
24 * It is highly reusable without source code modifications.
25 *
26 */
27
28 #include "noise1234.h"
29
30 // This is the new and improved, C(2) continuous interpolant
31 #define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) )
32
33 #define FASTFLOOR(x) ( ((int)(x)<(x)) ? ((int)x) : ((int)x-1 ) )
34 #define LERP(t, a, b) ((a) + (t)*((b)-(a)))
35
36
37 //---------------------------------------------------------------------
38 // Static data
39
40 /*
41 * Permutation table. This is just a random jumble of all numbers 0-255,
42 * repeated twice to avoid wrapping the index at 255 for each lookup.
43 * This needs to be exactly the same for all instances on all platforms,
44 * so it's easiest to just keep it as static explicit data.
45 * This also removes the need for any initialisation of this class.
46 *
47 * Note that making this an int[] instead of a char[] might make the
48 * code run faster on platforms with a high penalty for unaligned single
49 * byte addressing. Intel x86 is generally single-byte-friendly, but
50 * some other CPUs are faster with 4-aligned reads.
51 * However, a char[] is smaller, which avoids cache trashing, and that
52 * is probably the most important aspect on most architectures.
53 * This array is accessed a *lot* by the noise functions.
54 * A vector-valued noise over 3D accesses it 96 times, and a
55 * float-valued 4D noise 64 times. We want this to fit in the cache!
56 */
57 unsigned char perm[] = {151,160,137,91,90,15,
58 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
59 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
60 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
61 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
62 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
63 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
64 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
65 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
66 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
67 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
68 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
69 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
70 151,160,137,91,90,15,
71 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
72 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
73 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
74 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
75 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
76 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
77 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
78 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
79 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
80 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
81 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
82 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
83 };
84
85 //---------------------------------------------------------------------
86
87 /*
88 * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
89 * Note that these generate gradients of more than unit length. To make
90 * a close match with the value range of classic Perlin noise, the final
91 * noise values need to be rescaled. To match the RenderMan noise in a
92 * statistical sense, the approximate scaling values (empirically
93 * determined from test renderings) are:
94 * 1D noise needs rescaling with 0.188
95 * 2D noise needs rescaling with 0.507
96 * 3D noise needs rescaling with 0.936
97 * 4D noise needs rescaling with 0.87
98 * Note that these noise functions are the most practical and useful
99 * signed version of Perlin noise. To return values according to the
100 * RenderMan specification from the SL noise() and pnoise() functions,
101 * the noise values need to be scaled and offset to [0,1], like this:
102 * float SLnoise = (noise3(x,y,z) + 1.0) * 0.5;
103 */
104
grad1(int hash,float x)105 float grad1( int hash, float x ) {
106 int h = hash & 15;
107 float grad = 1.0 + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0
108 if (h&8) grad = -grad; // and a random sign for the gradient
109 return ( grad * x ); // Multiply the gradient with the distance
110 }
111
grad2(int hash,float x,float y)112 float grad2( int hash, float x, float y ) {
113 int h = hash & 7; // Convert low 3 bits of hash code
114 float u = h<4 ? x : y; // into 8 simple gradient directions,
115 float v = h<4 ? y : x; // and compute the dot product with (x,y).
116 return ((h&1)? -u : u) + ((h&2)? -2.0*v : 2.0*v);
117 }
118
grad3(int hash,float x,float y,float z)119 float grad3( int hash, float x, float y , float z ) {
120 int h = hash & 15; // Convert low 4 bits of hash code into 12 simple
121 float u = h<8 ? x : y; // gradient directions, and compute dot product.
122 float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15
123 return ((h&1)? -u : u) + ((h&2)? -v : v);
124 }
125
grad4(int hash,float x,float y,float z,float t)126 float grad4( int hash, float x, float y, float z, float t ) {
127 int h = hash & 31; // Convert low 5 bits of hash code into 32 simple
128 float u = h<24 ? x : y; // gradient directions, and compute dot product.
129 float v = h<16 ? y : z;
130 float w = h<8 ? z : t;
131 return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w);
132 }
133
134 //---------------------------------------------------------------------
135 /** 1D float Perlin noise, SL "noise()"
136 */
noise1(float x)137 float noise1( float x )
138 {
139 int ix0, ix1;
140 float fx0, fx1;
141 float s, n0, n1;
142
143 ix0 = FASTFLOOR( x ); // Integer part of x
144 fx0 = x - ix0; // Fractional part of x
145 fx1 = fx0 - 1.0f;
146 ix1 = ( ix0+1 ) & 0xff;
147 ix0 = ix0 & 0xff; // Wrap to 0..255
148
149 s = FADE( fx0 );
150
151 n0 = grad1( perm[ ix0 ], fx0 );
152 n1 = grad1( perm[ ix1 ], fx1 );
153 return 0.188f * ( LERP( s, n0, n1 ) );
154 }
155
156 //---------------------------------------------------------------------
157 /** 1D float Perlin periodic noise, SL "pnoise()"
158 */
pnoise1(float x,int px)159 float pnoise1( float x, int px )
160 {
161 int ix0, ix1;
162 float fx0, fx1;
163 float s, n0, n1;
164
165 ix0 = FASTFLOOR( x ); // Integer part of x
166 fx0 = x - ix0; // Fractional part of x
167 fx1 = fx0 - 1.0f;
168 ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 *and* wrap to 0..255
169 ix0 = ( ix0 % px ) & 0xff; // (because px might be greater than 256)
170
171 s = FADE( fx0 );
172
173 n0 = grad1( perm[ ix0 ], fx0 );
174 n1 = grad1( perm[ ix1 ], fx1 );
175 return 0.188f * ( LERP( s, n0, n1 ) );
176 }
177
178
179 //---------------------------------------------------------------------
180 /** 2D float Perlin noise.
181 */
noise2(float x,float y)182 float noise2( float x, float y )
183 {
184 int ix0, iy0, ix1, iy1;
185 float fx0, fy0, fx1, fy1;
186 float s, t, nx0, nx1, n0, n1;
187
188 ix0 = FASTFLOOR( x ); // Integer part of x
189 iy0 = FASTFLOOR( y ); // Integer part of y
190 fx0 = x - ix0; // Fractional part of x
191 fy0 = y - iy0; // Fractional part of y
192 fx1 = fx0 - 1.0f;
193 fy1 = fy0 - 1.0f;
194 ix1 = (ix0 + 1) & 0xff; // Wrap to 0..255
195 iy1 = (iy0 + 1) & 0xff;
196 ix0 = ix0 & 0xff;
197 iy0 = iy0 & 0xff;
198
199 t = FADE( fy0 );
200 s = FADE( fx0 );
201
202 nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
203 nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
204 n0 = LERP( t, nx0, nx1 );
205
206 nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
207 nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
208 n1 = LERP(t, nx0, nx1);
209
210 return 0.507f * ( LERP( s, n0, n1 ) );
211 }
212
213 //---------------------------------------------------------------------
214 /** 2D float Perlin periodic noise.
215 */
pnoise2(float x,float y,int px,int py)216 float pnoise2( float x, float y, int px, int py )
217 {
218 int ix0, iy0, ix1, iy1;
219 float fx0, fy0, fx1, fy1;
220 float s, t, nx0, nx1, n0, n1;
221
222 ix0 = FASTFLOOR( x ); // Integer part of x
223 iy0 = FASTFLOOR( y ); // Integer part of y
224 fx0 = x - ix0; // Fractional part of x
225 fy0 = y - iy0; // Fractional part of y
226 fx1 = fx0 - 1.0f;
227 fy1 = fy0 - 1.0f;
228 ix1 = (( ix0 + 1 ) % px) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
229 iy1 = (( iy0 + 1 ) % py) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
230 ix0 = ( ix0 % px ) & 0xff;
231 iy0 = ( iy0 % py ) & 0xff;
232
233 t = FADE( fy0 );
234 s = FADE( fx0 );
235
236 nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
237 nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
238 n0 = LERP( t, nx0, nx1 );
239
240 nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
241 nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
242 n1 = LERP(t, nx0, nx1);
243
244 return 0.507f * ( LERP( s, n0, n1 ) );
245 }
246
247
248 //---------------------------------------------------------------------
249 /** 3D float Perlin noise.
250 */
noise3(float x,float y,float z)251 float noise3( float x, float y, float z )
252 {
253 int ix0, iy0, ix1, iy1, iz0, iz1;
254 float fx0, fy0, fz0, fx1, fy1, fz1;
255 float s, t, r;
256 float nxy0, nxy1, nx0, nx1, n0, n1;
257
258 ix0 = FASTFLOOR( x ); // Integer part of x
259 iy0 = FASTFLOOR( y ); // Integer part of y
260 iz0 = FASTFLOOR( z ); // Integer part of z
261 fx0 = x - ix0; // Fractional part of x
262 fy0 = y - iy0; // Fractional part of y
263 fz0 = z - iz0; // Fractional part of z
264 fx1 = fx0 - 1.0f;
265 fy1 = fy0 - 1.0f;
266 fz1 = fz0 - 1.0f;
267 ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
268 iy1 = ( iy0 + 1 ) & 0xff;
269 iz1 = ( iz0 + 1 ) & 0xff;
270 ix0 = ix0 & 0xff;
271 iy0 = iy0 & 0xff;
272 iz0 = iz0 & 0xff;
273
274 r = FADE( fz0 );
275 t = FADE( fy0 );
276 s = FADE( fx0 );
277
278 nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
279 nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
280 nx0 = LERP( r, nxy0, nxy1 );
281
282 nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
283 nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
284 nx1 = LERP( r, nxy0, nxy1 );
285
286 n0 = LERP( t, nx0, nx1 );
287
288 nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
289 nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
290 nx0 = LERP( r, nxy0, nxy1 );
291
292 nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
293 nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
294 nx1 = LERP( r, nxy0, nxy1 );
295
296 n1 = LERP( t, nx0, nx1 );
297
298 return 0.936f * ( LERP( s, n0, n1 ) );
299 }
300
301 //---------------------------------------------------------------------
302 /** 3D float Perlin periodic noise.
303 */
pnoise3(float x,float y,float z,int px,int py,int pz)304 float pnoise3( float x, float y, float z, int px, int py, int pz )
305 {
306 int ix0, iy0, ix1, iy1, iz0, iz1;
307 float fx0, fy0, fz0, fx1, fy1, fz1;
308 float s, t, r;
309 float nxy0, nxy1, nx0, nx1, n0, n1;
310
311 ix0 = FASTFLOOR( x ); // Integer part of x
312 iy0 = FASTFLOOR( y ); // Integer part of y
313 iz0 = FASTFLOOR( z ); // Integer part of z
314 fx0 = x - ix0; // Fractional part of x
315 fy0 = y - iy0; // Fractional part of y
316 fz0 = z - iz0; // Fractional part of z
317 fx1 = fx0 - 1.0f;
318 fy1 = fy0 - 1.0f;
319 fz1 = fz0 - 1.0f;
320 ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
321 iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
322 iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
323 ix0 = ( ix0 % px ) & 0xff;
324 iy0 = ( iy0 % py ) & 0xff;
325 iz0 = ( iz0 % pz ) & 0xff;
326
327 r = FADE( fz0 );
328 t = FADE( fy0 );
329 s = FADE( fx0 );
330
331 nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
332 nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
333 nx0 = LERP( r, nxy0, nxy1 );
334
335 nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
336 nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
337 nx1 = LERP( r, nxy0, nxy1 );
338
339 n0 = LERP( t, nx0, nx1 );
340
341 nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
342 nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
343 nx0 = LERP( r, nxy0, nxy1 );
344
345 nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
346 nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
347 nx1 = LERP( r, nxy0, nxy1 );
348
349 n1 = LERP( t, nx0, nx1 );
350
351 return 0.936f * ( LERP( s, n0, n1 ) );
352 }
353
354
355 //---------------------------------------------------------------------
356 /** 4D float Perlin noise.
357 */
358
noise4(float x,float y,float z,float w)359 float noise4( float x, float y, float z, float w )
360 {
361 int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
362 float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
363 float s, t, r, q;
364 float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
365
366 ix0 = FASTFLOOR( x ); // Integer part of x
367 iy0 = FASTFLOOR( y ); // Integer part of y
368 iz0 = FASTFLOOR( z ); // Integer part of y
369 iw0 = FASTFLOOR( w ); // Integer part of w
370 fx0 = x - ix0; // Fractional part of x
371 fy0 = y - iy0; // Fractional part of y
372 fz0 = z - iz0; // Fractional part of z
373 fw0 = w - iw0; // Fractional part of w
374 fx1 = fx0 - 1.0f;
375 fy1 = fy0 - 1.0f;
376 fz1 = fz0 - 1.0f;
377 fw1 = fw0 - 1.0f;
378 ix1 = ( ix0 + 1 ) & 0xff; // Wrap to 0..255
379 iy1 = ( iy0 + 1 ) & 0xff;
380 iz1 = ( iz0 + 1 ) & 0xff;
381 iw1 = ( iw0 + 1 ) & 0xff;
382 ix0 = ix0 & 0xff;
383 iy0 = iy0 & 0xff;
384 iz0 = iz0 & 0xff;
385 iw0 = iw0 & 0xff;
386
387 q = FADE( fw0 );
388 r = FADE( fz0 );
389 t = FADE( fy0 );
390 s = FADE( fx0 );
391
392 nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
393 nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
394 nxy0 = LERP( q, nxyz0, nxyz1 );
395
396 nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
397 nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
398 nxy1 = LERP( q, nxyz0, nxyz1 );
399
400 nx0 = LERP ( r, nxy0, nxy1 );
401
402 nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
403 nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
404 nxy0 = LERP( q, nxyz0, nxyz1 );
405
406 nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
407 nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
408 nxy1 = LERP( q, nxyz0, nxyz1 );
409
410 nx1 = LERP ( r, nxy0, nxy1 );
411
412 n0 = LERP( t, nx0, nx1 );
413
414 nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
415 nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
416 nxy0 = LERP( q, nxyz0, nxyz1 );
417
418 nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
419 nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
420 nxy1 = LERP( q, nxyz0, nxyz1 );
421
422 nx0 = LERP ( r, nxy0, nxy1 );
423
424 nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
425 nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
426 nxy0 = LERP( q, nxyz0, nxyz1 );
427
428 nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
429 nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
430 nxy1 = LERP( q, nxyz0, nxyz1 );
431
432 nx1 = LERP ( r, nxy0, nxy1 );
433
434 n1 = LERP( t, nx0, nx1 );
435
436 return 0.87f * ( LERP( s, n0, n1 ) );
437 }
438
439 //---------------------------------------------------------------------
440 /** 4D float Perlin periodic noise.
441 */
442
pnoise4(float x,float y,float z,float w,int px,int py,int pz,int pw)443 float pnoise4( float x, float y, float z, float w,
444 int px, int py, int pz, int pw )
445 {
446 int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
447 float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
448 float s, t, r, q;
449 float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
450
451 ix0 = FASTFLOOR( x ); // Integer part of x
452 iy0 = FASTFLOOR( y ); // Integer part of y
453 iz0 = FASTFLOOR( z ); // Integer part of y
454 iw0 = FASTFLOOR( w ); // Integer part of w
455 fx0 = x - ix0; // Fractional part of x
456 fy0 = y - iy0; // Fractional part of y
457 fz0 = z - iz0; // Fractional part of z
458 fw0 = w - iw0; // Fractional part of w
459 fx1 = fx0 - 1.0f;
460 fy1 = fy0 - 1.0f;
461 fz1 = fz0 - 1.0f;
462 fw1 = fw0 - 1.0f;
463 ix1 = (( ix0 + 1 ) % px ) & 0xff; // Wrap to 0..px-1 and wrap to 0..255
464 iy1 = (( iy0 + 1 ) % py ) & 0xff; // Wrap to 0..py-1 and wrap to 0..255
465 iz1 = (( iz0 + 1 ) % pz ) & 0xff; // Wrap to 0..pz-1 and wrap to 0..255
466 iw1 = (( iw0 + 1 ) % pw ) & 0xff; // Wrap to 0..pw-1 and wrap to 0..255
467 ix0 = ( ix0 % px ) & 0xff;
468 iy0 = ( iy0 % py ) & 0xff;
469 iz0 = ( iz0 % pz ) & 0xff;
470 iw0 = ( iw0 % pw ) & 0xff;
471
472 q = FADE( fw0 );
473 r = FADE( fz0 );
474 t = FADE( fy0 );
475 s = FADE( fx0 );
476
477 nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
478 nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
479 nxy0 = LERP( q, nxyz0, nxyz1 );
480
481 nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
482 nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
483 nxy1 = LERP( q, nxyz0, nxyz1 );
484
485 nx0 = LERP ( r, nxy0, nxy1 );
486
487 nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
488 nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
489 nxy0 = LERP( q, nxyz0, nxyz1 );
490
491 nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
492 nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
493 nxy1 = LERP( q, nxyz0, nxyz1 );
494
495 nx1 = LERP ( r, nxy0, nxy1 );
496
497 n0 = LERP( t, nx0, nx1 );
498
499 nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
500 nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
501 nxy0 = LERP( q, nxyz0, nxyz1 );
502
503 nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
504 nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
505 nxy1 = LERP( q, nxyz0, nxyz1 );
506
507 nx0 = LERP ( r, nxy0, nxy1 );
508
509 nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
510 nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
511 nxy0 = LERP( q, nxyz0, nxyz1 );
512
513 nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
514 nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
515 nxy1 = LERP( q, nxyz0, nxyz1 );
516
517 nx1 = LERP ( r, nxy0, nxy1 );
518
519 n1 = LERP( t, nx0, nx1 );
520
521 return 0.87f * ( LERP( s, n0, n1 ) );
522 }
523
524 //---------------------------------------------------------------------
525