FastLED 3.9.15
Loading...
Searching...
No Matches

◆ snoise16() [4/4]

uint16_t snoise16 ( uint32_t x,
uint32_t y,
uint32_t z,
uint32_t w )

Definition at line 324 of file simplex.cpp.

324 {
325 // The skewing and unskewing factors are hairy again for the 4D case
326 const uint64_t F4 = 331804471; // .30: (Math.sqrt(5.0)-1.0)/4.0 = 0.30901699437494745
327 const uint64_t G4 = 593549882; // .32: (5.0-Math.sqrt(5.0))/20.0 = 0.1381966011250105
328
329 // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're
330 // in.
331 uint32_t s = (((uint64_t)x + (uint64_t)y + (uint64_t)z + (uint64_t)w) * F4) >> 32; // .12 + .30 = .10: Factor for 4D skewing.
332 uint32_t i = ((x>>2) + s) >> 10; // .0
333 uint32_t j = ((y>>2) + s) >> 10; // .0
334 uint32_t k = ((z>>2) + s) >> 10; // .0
335 uint32_t l = ((w>>2) + s) >> 10; // .0
336
337 uint64_t t = (((uint64_t)i + (uint64_t)j + (uint64_t)k + (uint64_t)l) * G4) >> 18; // .14
338 uint64_t X0 = ((uint64_t)i<<14) - t; // .14: Unskew the cell origin back to (x,y,z,w) space
339 uint64_t Y0 = ((uint64_t)j<<14) - t; // .14
340 uint64_t Z0 = ((uint64_t)k<<14) - t; // .14
341 uint64_t W0 = ((uint64_t)l<<14) - t; // .14
342 int32_t x0 = ((uint64_t)x<<2) - X0; // .14: The x,y,z,w distances from the cell origin
343 int32_t y0 = ((uint64_t)y<<2) - Y0; // .14
344 int32_t z0 = ((uint64_t)z<<2) - Z0; // .14
345 int32_t w0 = ((uint64_t)w<<2) - W0; // .14
346
347 // For the 4D case, the simplex is a 4D shape I won't even try to describe.
348 // To find out which of the 24 possible simplices we're in, we need to
349 // determine the magnitude ordering of x0, y0, z0 and w0.
350 // The method below is a good way of finding the ordering of x,y,z,w and
351 // then find the correct traversal order for the simplex we’re in.
352 // First, six pair-wise comparisons are performed between each possible pair
353 // of the four coordinates, and the results are used to add up binary bits
354 // for an integer index.
355 int c = 0;
356 if (x0 > y0) {
357 c += 32;
358 }
359 if (x0 > z0) {
360 c += 16;
361 }
362 if (y0 > z0) {
363 c += 8;
364 }
365 if (x0 > w0) {
366 c += 4;
367 }
368 if (y0 > w0) {
369 c += 2;
370 }
371 if (z0 > w0) {
372 c += 1;
373 }
374
375 // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
376 // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
377 // impossible. Only the 24 indices which have non-zero entries make any sense.
378 // We use a thresholding to set the coordinates in turn from the largest magnitude.
379 // The number 3 in the "simplex" array is at the position of the largest coordinate.
380 // The integer offsets for the second simplex corner
381 uint32_t i1 = simplex[c][0] >= 3 ? 1 : 0;
382 uint32_t j1 = simplex[c][1] >= 3 ? 1 : 0;
383 uint32_t k1 = simplex[c][2] >= 3 ? 1 : 0;
384 uint32_t l1 = simplex[c][3] >= 3 ? 1 : 0;
385 // The number 2 in the "simplex" array is at the second largest coordinate.
386 // The integer offsets for the third simplex corner
387 uint32_t i2 = simplex[c][0] >= 2 ? 1 : 0;
388 uint32_t j2 = simplex[c][1] >= 2 ? 1 : 0;
389 uint32_t k2 = simplex[c][2] >= 2 ? 1 : 0;
390 uint32_t l2 = simplex[c][3] >= 2 ? 1 : 0;
391 // The number 1 in the "simplex" array is at the second smallest coordinate.
392 // The integer offsets for the fourth simplex corner
393 uint32_t i3 = simplex[c][0] >= 1 ? 1 : 0;
394 uint32_t j3 = simplex[c][1] >= 1 ? 1 : 0;
395 uint32_t k3 = simplex[c][2] >= 1 ? 1 : 0;
396 uint32_t l3 = simplex[c][3] >= 1 ? 1 : 0;
397 // The fifth corner has all coordinate offsets = 1, so no need to look that up.
398
399 int32_t x1 = x0 - ((int32_t)i1<<14) + (int32_t)(G4>>18); // .14: Offsets for second corner in (x,y,z,w) coords
400 int32_t y1 = y0 - ((int32_t)j1<<14) + (int32_t)(G4>>18);
401 int32_t z1 = z0 - ((int32_t)k1<<14) + (int32_t)(G4>>18);
402 int32_t w1 = w0 - ((int32_t)l1<<14) + (int32_t)(G4>>18);
403 int32_t x2 = x0 - ((int32_t)i2<<14) + (int32_t)(2*G4>>18); // .14: Offsets for third corner in (x,y,z,w) coords
404 int32_t y2 = y0 - ((int32_t)j2<<14) + (int32_t)(2*G4>>18);
405 int32_t z2 = z0 - ((int32_t)k2<<14) + (int32_t)(2*G4>>18);
406 int32_t w2 = w0 - ((int32_t)l2<<14) + (int32_t)(2*G4>>18);
407 int32_t x3 = x0 - ((int32_t)i3<<14) + (int32_t)(3*G4>>18); // .14: Offsets for fourth corner in (x,y,z,w) coords
408 int32_t y3 = y0 - ((int32_t)j3<<14) + (int32_t)(3*G4>>18);
409 int32_t z3 = z0 - ((int32_t)k3<<14) + (int32_t)(3*G4>>18);
410 int32_t w3 = w0 - ((int32_t)l3<<14) + (int32_t)(3*G4>>18);
411 int32_t x4 = x0 - (1 << 14) + (int32_t)(4*G4>>18); // .14: Offsets for last corner in (x,y,z,w) coords
412 int32_t y4 = y0 - (1 << 14) + (int32_t)(4*G4>>18);
413 int32_t z4 = z0 - (1 << 14) + (int32_t)(4*G4>>18);
414 int32_t w4 = w0 - (1 << 14) + (int32_t)(4*G4>>18);
415
416 int32_t n0 = 0, n1 = 0, n2 = 0, n3 = 0, n4 = 0; // Noise contributions from the five corners
417 const int32_t fix0_6 = 161061274; // .28: 0.6
418
419 // Calculate the contribution from the five corners
420 int32_t t0 = (fix0_6 - x0*x0 - y0*y0 - z0*z0 - w0*w0) >> 12; // .16
421 if (t0 > 0) {
422 t0 = (t0 * t0) >> 16;
423 t0 = (t0 * t0) >> 16;
424 // .16 * .14 = .30
425 n0 = t0 * grad(P((i+(uint32_t)(P((j+(uint32_t)(P((k+(uint32_t)(P(l&0xff)))&0xff)))&0xff)))&0xff), x0, y0, z0, w0);
426 }
427
428 int32_t t1 = (fix0_6 - x1*x1 - y1*y1 - z1*z1 - w1*w1) >> 12; // .16
429 if (t1 > 0) {
430 t1 = (t1 * t1) >> 16;
431 t1 = (t1 * t1) >> 16;
432 // .16 * .14 = .30
433 n1 = t1 * grad(P((i+i1+(uint32_t)(P((j+j1+(uint32_t)(P((k+k1+(uint32_t)(P((l+l1)&0xff)))&0xff)))&0xff)))&0xff), x1, y1, z1, w1);
434 }
435
436 int32_t t2 = (fix0_6 - x2*x2 - y2*y2 - z2*z2 - w2*w2) >> 12; // .16
437 if (t2 > 0) {
438 t2 = (t2 * t2) >> 16;
439 t2 = (t2 * t2) >> 16;
440 // .16 * .14 = .30
441 n2 = t2 * grad(P((i+i2+(uint32_t)(P((j+j2+(uint32_t)(P((k+k2+(uint32_t)(P((l+l2)&0xff)))&0xff)))&0xff)))&0xff), x2, y2, z2, w2);
442 }
443
444 int32_t t3 = (fix0_6 - x3*x3 - y3*y3 - z3*z3 - w3*w3) >> 12; // .16
445 if (t3 > 0) {
446 t3 = (t3 * t3) >> 16;
447 t3 = (t3 * t3) >> 16;
448 // .16 * .14 = .30
449 n3 = t3 * grad(P((i+i3+(uint32_t)(P((j+j3+(uint32_t)(P((k+k3+(uint32_t)(P((l+l3)&0xff)))&0xff)))&0xff)))&0xff), x3, y3, z3, w3);
450 }
451
452 int32_t t4 = (fix0_6 - x4*x4 - y4*y4 - z4*z4 - w4*w4) >> 12; // .16
453 if (t4 > 0) {
454 t4 = (t4 * t4) >> 16;
455 t4 = (t4 * t4) >> 16;
456 // .16 * .14 = .30
457 n4 = t4 * grad(P((i+1+(uint32_t)(P((j+1+(uint32_t)(P((k+1+(uint32_t)(P((l+1)&0xff)))&0xff)))&0xff)))&0xff), x4, y4, z4, w4);
458 }
459
460 int32_t n = n0 + n1 + n2 + n3 + n4; // .30
461 n = ((n >> 8) * 13832) >> 16; // fix scale
462 return uint16_t(n) + 0x8000;
463}
uint32_t z[NUM_LAYERS]
Definition Fire2023.ino:82
uint32_t x[NUM_LAYERS]
Definition Fire2023.ino:80
uint32_t y[NUM_LAYERS]
Definition Fire2023.ino:81
@ W0
White is first.
Definition eorder.h:28
#define P(x)
Definition simplex.cpp:33
static int32_t grad(uint8_t hash, int32_t x)
Definition simplex.cpp:70
static uint8_t const simplex[64][4]
Definition simplex.cpp:57

References grad(), P, simplex, W0, x, y, and z.

+ Here is the call graph for this function: