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