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