FastLED 3.10.8
Loading...
Searching...
No Matches
noise.cpp.hpp
Go to the documentation of this file.
1
3
4#include "platforms/is_platform.h"
5
6// IWYU pragma: begin_keep
7#include <string.h>
8// IWYU pragma: end_keep // ok include
9#include "fl/stl/array.h"
10
11
13#define FASTLED_INTERNAL
14#include "fl/system/fastled.h"
15
16
18#include "fl/stl/cstring.h"
19#include "fl/math/math.h"
20#include "fl/stl/noexcept.h"
21// Compiler throws a warning about stack usage possibly being unbounded even
22// though bounds are checked, silence that so users don't see it
24#if defined(FL_IS_GCC)
25 FL_DISABLE_WARNING(stack-usage=)
26#elif defined(FL_IS_CLANG)
27 FL_DISABLE_WARNING(unknown-warning-option)
28#endif
29
30
31
33#define NOISE_P(x) FL_PGM_READ_BYTE_NEAR(noise_detail::p + x)
34
35
36namespace noise_detail {
37
38FL_PROGMEM static fl::u8 const p[] = {
39 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225,
40 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148,
41 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32,
42 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175,
43 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122,
44 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54,
45 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169,
46 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64,
47 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212,
48 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213,
49 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
50 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
51 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241,
52 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157,
53 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93,
54 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
55 151};
56
57
58// Start Doxygen define hiding
60
61#if FASTLED_NOISE_ALLOW_AVERAGE_TO_OVERFLOW == 1
62#define AVG15(U,V) (((U)+(V)) >> 1)
63#else
64// See if we should use the inlined avg15 for AVR with MUL instruction
65#if defined(FL_IS_AVR) && !defined(FL_IS_AVR_ATTINY)
66#define AVG15(U,V) (noise_detail::avg15_inline_avr_mul((U),(V)))
67// inlined copy of avg15 for AVR with MUL instruction; cloned from math8.h
68// Forcing this inline in the 3-D 16bit noise produces a 12% speedup overall,
69// at a cost of just +8 bytes of net code size.
70static fl::i16 inline __attribute__((always_inline)) avg15_inline_avr_mul( fl::i16 i, fl::i16 j) FL_NO_EXCEPT
71{
72 asm volatile(
73 /* first divide j by 2, throwing away lowest bit */
74 "asr %B[j] \n\t"
75 "ror %A[j] \n\t"
76 /* now divide i by 2, with lowest bit going into C */
77 "asr %B[i] \n\t"
78 "ror %A[i] \n\t"
79 /* add j + C to i */
80 "adc %A[i], %A[j] \n\t"
81 "adc %B[i], %B[j] \n\t"
82 : [i] "+r" (i)
83 : [j] "r" (j) );
84 return i;
85}
86#else
87#define AVG15(U,V) (fl::avg15((U),(V)))
88#endif
89#endif
90
91// See fastled_config.h for notes on this;
92// "#define FASTLED_NOISE_FIXED 1" is the correct value
93#if FASTLED_NOISE_FIXED == 0
94#define EASE8(x) (FADE(x) )
95#define EASE16(x) (FADE(x) )
96#else
97#define EASE8(x) (ease8InOutQuad(x) )
98#define EASE16(x) (ease16InOutQuad(x))
99#endif
100//
101// #define FADE_12
102#define FADE_16
103
104#ifdef FADE_12
105#define FADE logfade12
106#define LERP(a,b,u) lerp15by12(a,b,u)
107#else
108#define FADE(x) scale16(x,x)
109#define LERP(a,b,u) lerp15by16(a,b,u)
110#endif
111
112// end Doxygen define hiding
114
115} // namespace noise_detail
116
117static fl::i16 inline __attribute__((always_inline)) grad16(fl::u8 hash, fl::i16 x, fl::i16 y, fl::i16 z) FL_NO_EXCEPT {
118#if 0
119 switch(hash & 0xF) {
120 case 0: return (( x) + ( y))>>1;
121 case 1: return ((-x) + ( y))>>1;
122 case 2: return (( x) + (-y))>>1;
123 case 3: return ((-x) + (-y))>>1;
124 case 4: return (( x) + ( z))>>1;
125 case 5: return ((-x) + ( z))>>1;
126 case 6: return (( x) + (-z))>>1;
127 case 7: return ((-x) + (-z))>>1;
128 case 8: return (( y) + ( z))>>1;
129 case 9: return ((-y) + ( z))>>1;
130 case 10: return (( y) + (-z))>>1;
131 case 11: return ((-y) + (-z))>>1;
132 case 12: return (( y) + ( x))>>1;
133 case 13: return ((-y) + ( z))>>1;
134 case 14: return (( y) + (-x))>>1;
135 case 15: return ((-y) + (-z))>>1;
136 }
137#else
138 hash = hash&15;
139 fl::i16 u = hash<8?x:y;
140 fl::i16 v = hash<4?y:hash==12||hash==14?x:z;
141 if(hash&1) { u = -u; }
142 if(hash&2) { v = -v; }
143
144 return AVG15(u,v);
145#endif
146}
147
148static fl::i16 inline __attribute__((always_inline)) grad16(fl::u8 hash, fl::i16 x, fl::i16 y) FL_NO_EXCEPT {
149 hash = hash & 7;
150 fl::i16 u,v;
151 if(hash < 4) { u = x; v = y; } else { u = y; v = x; }
152 if(hash&1) { u = -u; }
153 if(hash&2) { v = -v; }
154
155 return AVG15(u,v);
156}
157
158#if FASTLED_NOISE_FIXED == 0
159static fl::i16 inline __attribute__((always_inline)) grad16(fl::u8 hash, fl::i16 x) FL_NO_EXCEPT {
160 hash = hash & 15;
161 fl::i16 u,v;
162 if(hash > 8) { u=x;v=x; }
163 else if(hash < 4) { u=x;v=1; }
164 else { u=1;v=x; }
165 if(hash&1) { u = -u; }
166 if(hash&2) { v = -v; }
167
168 return AVG15(u,v);
169}
170#else
175static fl::i16 inline __attribute__((always_inline)) grad16(fl::u8 hash, fl::i16 x) FL_NO_EXCEPT {
176 return (hash & 1) ? static_cast<fl::i16>(-x) : x;
177}
178#endif
179
180// selectBasedOnHashBit performs this:
181// result = (hash & (1<<bitnumber)) ? a : b
182// but with an AVR asm version that's smaller and quicker than C
183// (and probably not worth including in lib8tion)
184static fl::i8 inline __attribute__((always_inline)) __attribute__((unused)) selectBasedOnHashBit(fl::u8 hash, fl::u8 bitnumber, fl::i8 a, fl::i8 b) FL_NO_EXCEPT {
185 fl::i8 result;
186#if !defined(FL_IS_AVR)
187 result = (hash & (1<<bitnumber)) ? a : b;
188#else
189 asm volatile(
190 "mov %[result],%[a] \n\t"
191 "sbrs %[hash],%[bitnumber] \n\t"
192 "mov %[result],%[b] \n\t"
193 : [result] "=r" (result)
194 : [hash] "r" (hash),
195 [bitnumber] "M" (bitnumber),
196 [a] "r" (a),
197 [b] "r" (b)
198 );
199#endif
200 return result;
201}
202
203static fl::i8 inline __attribute__((always_inline)) grad8(fl::u8 hash, fl::i8 x, fl::i8 y, fl::i8 z) FL_NO_EXCEPT {
204 // Industry-standard 3D Perlin noise gradient implementation
205 // Uses proper 12 edge vectors of a cube for maximum range coverage
206
207 switch(hash & 0xF) {
208 case 0: return fl::avg7( x, y); // (1,1,0)
209 case 1: return fl::avg7(-x, y); // (-1,1,0)
210 case 2: return fl::avg7( x, -y); // (1,-1,0)
211 case 3: return fl::avg7(-x, -y); // (-1,-1,0)
212 case 4: return fl::avg7( x, z); // (1,0,1)
213 case 5: return fl::avg7(-x, z); // (-1,0,1)
214 case 6: return fl::avg7( x, -z); // (1,0,-1)
215 case 7: return fl::avg7(-x, -z); // (-1,0,-1)
216 case 8: return fl::avg7( y, z); // (0,1,1)
217 case 9: return fl::avg7(-y, z); // (0,-1,1)
218 case 10: return fl::avg7( y, -z); // (0,1,-1)
219 case 11: return fl::avg7(-y, -z); // (0,-1,-1)
220 // Repeat first 4 for hash values 12-15 (proper wrap-around)
221 case 12: return fl::avg7( x, y); // (1,1,0)
222 case 13: return fl::avg7(-x, y); // (-1,1,0)
223 case 14: return fl::avg7( x, -y); // (1,-1,0)
224 case 15: return fl::avg7(-x, -y); // (-1,-1,0)
225 }
226 return 0; // Should never reach here
227}
228
229static fl::i8 inline __attribute__((always_inline)) grad8(fl::u8 hash, fl::i8 x, fl::i8 y) FL_NO_EXCEPT
230{
231 // since the tests below can be done bit-wise on the bottom
232 // three bits, there's no need to mask off the higher bits
233 // hash = hash & 7;
234
235 fl::i8 u,v;
236 if( hash & 4) {
237 u = y; v = x;
238 } else {
239 u = x; v = y;
240 }
241
242 if(hash&1) { u = -u; }
243 if(hash&2) { v = -v; }
244
245 return fl::avg7(u,v);
246}
247
248#if FASTLED_NOISE_FIXED == 0
249static fl::i8 inline __attribute__((always_inline)) grad8(fl::u8 hash, fl::i8 x) FL_NO_EXCEPT
250{
251 // since the tests below can be done bit-wise on the bottom
252 // four bits, there's no need to mask off the higher bits
253 // hash = hash & 15;
254
255 fl::i8 u,v;
256 if(hash & 8) {
257 u=x; v=x;
258 } else {
259 if(hash & 4) {
260 u=1; v=x;
261 } else {
262 u=x; v=1;
263 }
264 }
265
266 if(hash&1) { u = -u; }
267 if(hash&2) { v = -v; }
268
269 return fl::avg7(u,v);
270}
271#else
292static fl::i8 inline __attribute__((always_inline)) grad8(fl::u8 hash, fl::i8 x) FL_NO_EXCEPT
293{
294 return (hash & 1) ? static_cast<fl::i8>(-x) : x;
295}
296#endif
297
298
299#ifdef FADE_12
300fl::u16 logfade12(fl::u16 val) {
301 return scale16(val,val)>>4;
302}
303
304static fl::i16 inline __attribute__((always_inline)) lerp15by12( fl::i16 a, fl::i16 b, fract16 frac) FL_NO_EXCEPT
305{
306 //if(1) return (lerp(frac,a,b));
307 fl::i16 result;
308 if( b > a) {
309 fl::u16 delta = b - a;
310 fl::u16 scaled = scale16(delta,frac<<4);
311 result = a + scaled;
312 } else {
313 fl::u16 delta = a - b;
314 fl::u16 scaled = scale16(delta,frac<<4);
315 result = a - scaled;
316 }
317 return result;
318}
319#endif
320
321static fl::i8 inline __attribute__((always_inline)) lerp7by8( fl::i8 a, fl::i8 b, fract8 frac) FL_NO_EXCEPT
322{
323 // int8_t delta = b - a;
324 // int16_t prod = (uint16_t)delta * (uint16_t)frac;
325 // int8_t scaled = prod >> 8;
326 // int8_t result = a + scaled;
327 // return result;
328 fl::i8 result;
329 if( b > a) {
330 fl::u8 delta = b - a;
331 fl::u8 scaled = scale8( delta, frac);
332 result = a + scaled;
333 } else {
334 fl::u8 delta = a - b;
335 fl::u8 scaled = scale8( delta, frac);
336 result = a - scaled;
337 }
338 return result;
339}
340
341fl::i16 inoise16_raw(fl::u32 x, fl::u32 y, fl::u32 z)
343 // Find the unit cube containing the point
344 fl::u8 X = (x>>16)&0xFF;
345 fl::u8 Y = (y>>16)&0xFF;
346 fl::u8 Z = (z>>16)&0xFF;
347
348 // Hash cube corner coordinates
349 fl::u8 A = NOISE_P(X)+Y;
350 fl::u8 AA = NOISE_P(A)+Z;
351 fl::u8 AB = NOISE_P(A+1)+Z;
352 fl::u8 B = NOISE_P(X+1)+Y;
353 fl::u8 BA = NOISE_P(B) + Z;
354 fl::u8 BB = NOISE_P(B+1)+Z;
355
356 // Get the relative position of the point in the cube
357 fl::u16 u = x & 0xFFFF;
358 fl::u16 v = y & 0xFFFF;
359 fl::u16 w = z & 0xFFFF;
360
361 // Get a signed version of the above for the grad function
362 fl::i16 xx = (u >> 1) & 0x7FFF;
363 fl::i16 yy = (v >> 1) & 0x7FFF;
364 fl::i16 zz = (w >> 1) & 0x7FFF;
365 fl::u16 N = 0x8000L;
366
367 u = EASE16(u); v = EASE16(v); w = EASE16(w);
368
369 // skip the log fade adjustment for the moment, otherwise here we would
370 // adjust fade values for u,v,w
371 fl::i16 X1 = LERP(grad16(NOISE_P(AA), xx, yy, zz), grad16(NOISE_P(BA), xx - N, yy, zz), u);
372 fl::i16 X2 = LERP(grad16(NOISE_P(AB), xx, yy-N, zz), grad16(NOISE_P(BB), xx - N, yy - N, zz), u);
373 fl::i16 X3 = LERP(grad16(NOISE_P(AA+1), xx, yy, zz-N), grad16(NOISE_P(BA+1), xx - N, yy, zz-N), u);
374 fl::i16 X4 = LERP(grad16(NOISE_P(AB+1), xx, yy-N, zz-N), grad16(NOISE_P(BB+1), xx - N, yy - N, zz - N), u);
375
376 fl::i16 Y1 = LERP(X1,X2,v);
377 fl::i16 Y2 = LERP(X3,X4,v);
378
379 fl::i16 ans = LERP(Y1,Y2,w);
380
381 return ans;
382}
383
384fl::i16 inoise16_raw(fl::u32 x, fl::u32 y, fl::u32 z, fl::u32 t) FL_NO_EXCEPT {
385 // 1. Extract the integer (grid) parts.
386 fl::u8 X = (x >> 16) & 0xFF;
387 fl::u8 Y = (y >> 16) & 0xFF;
388 fl::u8 Z = (z >> 16) & 0xFF;
389 fl::u8 T = (t >> 16) & 0xFF;
390
391 // 2. Extract the fractional parts.
392 fl::u16 u = x & 0xFFFF;
393 fl::u16 v = y & 0xFFFF;
394 fl::u16 w = z & 0xFFFF;
395 fl::u16 s = t & 0xFFFF;
396
397 // 3. Easing of the fractional parts.
398 u = EASE16(u);
399 v = EASE16(v);
400 w = EASE16(w);
401 s = EASE16(s);
402
403 fl::u16 N = 0x8000L; // fixed-point half-scale
404
405 // 4. Precompute fixed-point versions for the gradient evaluations.
406 fl::i16 xx = (u >> 1) & 0x7FFF;
407 fl::i16 yy = (v >> 1) & 0x7FFF;
408 fl::i16 zz = (w >> 1) & 0x7FFF;
409
410 // 5. Hash the 3D cube corners (the “base” for both t slices).
411 fl::u8 A = NOISE_P(X) + Y;
412 fl::u8 AA = NOISE_P(A) + Z;
413 fl::u8 AB = NOISE_P(A + 1) + Z;
414 fl::u8 B = NOISE_P(X + 1) + Y;
415 fl::u8 BA = NOISE_P(B) + Z;
416 fl::u8 BB = NOISE_P(B + 1) + Z;
417
418 // 6. --- Lower t Slice (using T) ---
419 fl::u8 AAA = NOISE_P(AA) + T;
420 fl::u8 AAB = NOISE_P(AA + 1) + T;
421 fl::u8 ABA = NOISE_P(AB) + T;
422 fl::u8 ABB = NOISE_P(AB + 1) + T;
423 fl::u8 BAA = NOISE_P(BA) + T;
424 fl::u8 BAB = NOISE_P(BA + 1) + T;
425 fl::u8 BBA = NOISE_P(BB) + T;
426 fl::u8 BBB = NOISE_P(BB + 1) + T;
427
428 fl::i16 L1 = LERP(grad16(AAA, xx, yy, zz), grad16(BAA, xx - N, yy, zz), u);
429 fl::i16 L2 = LERP(grad16(ABA, xx, yy - N, zz), grad16(BBA, xx - N, yy - N, zz), u);
430 fl::i16 L3 = LERP(grad16(AAB, xx, yy, zz - N), grad16(BAB, xx - N, yy, zz - N), u);
431 fl::i16 L4 = LERP(grad16(ABB, xx, yy - N, zz - N), grad16(BBB, xx - N, yy - N, zz - N), u);
432
433 fl::i16 Y1 = LERP(L1, L2, v);
434 fl::i16 Y2 = LERP(L3, L4, v);
435 fl::i16 noise_lower = LERP(Y1, Y2, w);
436
437 // 7. --- Upper t Slice (using T+1) ---
438 fl::u8 Tupper = T + 1;
439 fl::u8 AAA_u = NOISE_P(AA) + Tupper;
440 fl::u8 AAB_u = NOISE_P(AA + 1) + Tupper;
441 fl::u8 ABA_u = NOISE_P(AB) + Tupper;
442 fl::u8 ABB_u = NOISE_P(AB + 1) + Tupper;
443 fl::u8 BAA_u = NOISE_P(BA) + Tupper;
444 fl::u8 BAB_u = NOISE_P(BA + 1) + Tupper;
445 fl::u8 BBA_u = NOISE_P(BB) + Tupper;
446 fl::u8 BBB_u = NOISE_P(BB + 1) + Tupper;
447
448 fl::i16 U1 = LERP(grad16(AAA_u, xx, yy, zz), grad16(BAA_u, xx - N, yy, zz), u);
449 fl::i16 U2 = LERP(grad16(ABA_u, xx, yy - N, zz), grad16(BBA_u, xx - N, yy - N, zz), u);
450 fl::i16 U3 = LERP(grad16(AAB_u, xx, yy, zz - N), grad16(BAB_u, xx - N, yy, zz - N), u);
451 fl::i16 U4 = LERP(grad16(ABB_u, xx, yy - N, zz - N), grad16(BBB_u, xx - N, yy - N, zz - N), u);
452
453 fl::i16 V1 = LERP(U1, U2, v);
454 fl::i16 V2 = LERP(U3, U4, v);
455 fl::i16 noise_upper = LERP(V1, V2, w);
456
457 // 8. Final interpolation in the t dimension.
458 fl::i16 noise4d = LERP(noise_lower, noise_upper, s);
459
460 return noise4d;
461}
462
463fl::u16 inoise16(fl::u32 x, fl::u32 y, fl::u32 z, fl::u32 t) FL_NO_EXCEPT {
464 fl::i32 ans = inoise16_raw(x,y,z,t);
465 ans = ans + 19052L;
466 fl::u32 pan = ans;
467 // pan = (ans * 220L) >> 7. That's the same as:
468 // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
469 // Identical math, except for the highest bit, which we don't care about anyway,
470 // since we're returning the 'middle' 16 out of a 32-bit value anyway.
471 pan *= 440L;
472 return (pan>>8);
473
474 // return scale16by8(pan,220)<<1;
475 // return ((inoise16_raw(x,y,z)+19052)*220)>>7;
476 // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1;
477}
478
479fl::u16 inoise16(fl::u32 x, fl::u32 y, fl::u32 z) FL_NO_EXCEPT {
480 fl::i32 ans = inoise16_raw(x,y,z);
481 ans = ans + 19052L;
482 fl::u32 pan = ans;
483 // pan = (ans * 220L) >> 7. That's the same as:
484 // pan = (ans * 440L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
485 // Identical math, except for the highest bit, which we don't care about anyway,
486 // since we're returning the 'middle' 16 out of a 32-bit value anyway.
487 pan *= 440L;
488 return (pan>>8);
489
490 // // return scale16by8(pan,220)<<1;
491 // return ((inoise16_raw(x,y,z)+19052)*220)>>7;
492 // return scale16by8(inoise16_raw(x,y,z)+19052,220)<<1;
493}
494
495fl::i16 inoise16_raw(fl::u32 x, fl::u32 y)
497 // Find the unit cube containing the point
498 fl::u8 X = x>>16;
499 fl::u8 Y = y>>16;
500
501 // Hash cube corner coordinates
502 fl::u8 A = NOISE_P(X)+Y;
503 fl::u8 AA = NOISE_P(A);
504 fl::u8 AB = NOISE_P(A+1);
505 fl::u8 B = NOISE_P(X+1)+Y;
506 fl::u8 BA = NOISE_P(B);
507 fl::u8 BB = NOISE_P(B+1);
508
509 // Get the relative position of the point in the cube
510 fl::u16 u = x & 0xFFFF;
511 fl::u16 v = y & 0xFFFF;
512
513 // Get a signed version of the above for the grad function
514 fl::i16 xx = (u >> 1) & 0x7FFF;
515 fl::i16 yy = (v >> 1) & 0x7FFF;
516 fl::u16 N = 0x8000L;
517
518 u = EASE16(u); v = EASE16(v);
519
520 fl::i16 X1 = LERP(grad16(NOISE_P(AA), xx, yy), grad16(NOISE_P(BA), xx - N, yy), u);
521 fl::i16 X2 = LERP(grad16(NOISE_P(AB), xx, yy-N), grad16(NOISE_P(BB), xx - N, yy - N), u);
522
523 fl::i16 ans = LERP(X1,X2,v);
524
525 return ans;
526}
527
528fl::u16 inoise16(fl::u32 x, fl::u32 y) FL_NO_EXCEPT {
529 fl::i32 ans = inoise16_raw(x,y);
530 ans = ans + 17308L;
531 fl::u32 pan = ans;
532 // pan = (ans * 242L) >> 7. That's the same as:
533 // pan = (ans * 484L) >> 8. And this way avoids a 7X four-byte shift-loop on AVR.
534 // Identical math, except for the highest bit, which we don't care about anyway,
535 // since we're returning the 'middle' 16 out of a 32-bit value anyway.
536 pan *= 484L;
537 return (pan>>8);
538
539 // return (uint32_t)(((int32_t)inoise16_raw(x,y)+(uint32_t)17308)*242)>>7;
540 // return scale16by8(inoise16_raw(x,y)+17308,242)<<1;
541}
542
543fl::i16 inoise16_raw(fl::u32 x)
545 // Find the unit cube containing the point
546 fl::u8 X = x>>16;
547
548 // Hash cube corner coordinates
549 fl::u8 A = NOISE_P(X);
550 fl::u8 AA = NOISE_P(A);
551 fl::u8 B = NOISE_P(X+1);
552 fl::u8 BA = NOISE_P(B);
553
554 // Get the relative position of the point in the cube
555 fl::u16 u = x & 0xFFFF;
556
557 // Get a signed version of the above for the grad function
558 fl::i16 xx = (u >> 1) & 0x7FFF;
559 fl::u16 N = 0x8000L;
560
561 u = EASE16(u);
562
563 fl::i16 ans = LERP(grad16(NOISE_P(AA), xx), grad16(NOISE_P(BA), xx - N), u);
564
565 return ans;
566}
567
568fl::u16 inoise16(fl::u32 x) FL_NO_EXCEPT {
569 return ((fl::u32)((fl::i32)inoise16_raw(x) + 17308L)) << 1;
570}
571
572fl::i8 inoise8_raw(fl::u16 x, fl::u16 y, fl::u16 z)
574 // Find the unit cube containing the point
575 fl::u8 X = x>>8;
576 fl::u8 Y = y>>8;
577 fl::u8 Z = z>>8;
578
579 // Hash cube corner coordinates
580 fl::u8 A = NOISE_P(X)+Y;
581 fl::u8 AA = NOISE_P(A)+Z;
582 fl::u8 AB = NOISE_P(A+1)+Z;
583 fl::u8 B = NOISE_P(X+1)+Y;
584 fl::u8 BA = NOISE_P(B) + Z;
585 fl::u8 BB = NOISE_P(B+1)+Z;
586
587 // Get the relative position of the point in the cube
588 fl::u8 u = x;
589 fl::u8 v = y;
590 fl::u8 w = z;
591
592 // Get a signed version of the above for the grad function
593 fl::i8 xx = ((fl::u8)(x)>>1) & 0x7F;
594 fl::i8 yy = ((fl::u8)(y)>>1) & 0x7F;
595 fl::i8 zz = ((fl::u8)(z)>>1) & 0x7F;
596 fl::u8 N = 0x80;
597
598 u = EASE8(u); v = EASE8(v); w = EASE8(w);
599
600 fl::i8 X1 = lerp7by8(grad8(NOISE_P(AA), xx, yy, zz), grad8(NOISE_P(BA), xx - N, yy, zz), u);
601 fl::i8 X2 = lerp7by8(grad8(NOISE_P(AB), xx, yy-N, zz), grad8(NOISE_P(BB), xx - N, yy - N, zz), u);
602 fl::i8 X3 = lerp7by8(grad8(NOISE_P(AA+1), xx, yy, zz-N), grad8(NOISE_P(BA+1), xx - N, yy, zz-N), u);
603 fl::i8 X4 = lerp7by8(grad8(NOISE_P(AB+1), xx, yy-N, zz-N), grad8(NOISE_P(BB+1), xx - N, yy - N, zz - N), u);
604
605 fl::i8 Y1 = lerp7by8(X1,X2,v);
606 fl::i8 Y2 = lerp7by8(X3,X4,v);
607
608 fl::i8 ans = lerp7by8(Y1,Y2,w);
609
610 return ans;
611}
612
613fl::u8 inoise8(fl::u16 x, fl::u16 y, fl::u16 z) FL_NO_EXCEPT {
614 //return scale8(76+(inoise8_raw(x,y,z)),215)<<1;
615 fl::i8 n = inoise8_raw( x, y, z); // -64..+64
616 n+= 64; // 0..128
617 fl::u8 ans = qadd8( n, n); // 0..255
618 return ans;
619}
620
621fl::i8 inoise8_raw(fl::u16 x, fl::u16 y)
623 // Find the unit cube containing the point
624 fl::u8 X = x>>8;
625 fl::u8 Y = y>>8;
626
627 // Hash cube corner coordinates
628 fl::u8 A = NOISE_P(X)+Y;
629 fl::u8 AA = NOISE_P(A);
630 fl::u8 AB = NOISE_P(A+1);
631 fl::u8 B = NOISE_P(X+1)+Y;
632 fl::u8 BA = NOISE_P(B);
633 fl::u8 BB = NOISE_P(B+1);
634
635 // Get the relative position of the point in the cube
636 fl::u8 u = x;
637 fl::u8 v = y;
638
639 // Get a signed version of the above for the grad function
640 fl::i8 xx = ((fl::u8)(x)>>1) & 0x7F;
641 fl::i8 yy = ((fl::u8)(y)>>1) & 0x7F;
642 fl::u8 N = 0x80;
643
644 u = EASE8(u); v = EASE8(v);
645
646 fl::i8 X1 = lerp7by8(grad8(NOISE_P(AA), xx, yy), grad8(NOISE_P(BA), xx - N, yy), u);
647 fl::i8 X2 = lerp7by8(grad8(NOISE_P(AB), xx, yy-N), grad8(NOISE_P(BB), xx - N, yy - N), u);
648
649 fl::i8 ans = lerp7by8(X1,X2,v);
650
651 return ans;
652 // return scale8((70+(ans)),234)<<1;
653}
654
655
656
657fl::u8 inoise8(fl::u16 x, fl::u16 y) FL_NO_EXCEPT {
658 //return scale8(69+inoise8_raw(x,y),237)<<1;
659 fl::i8 n = inoise8_raw( x, y); // -64..+64
660 n+= 64; // 0..128
661 fl::u8 ans = qadd8( n, n); // 0..255
662 return ans;
663}
664
665// output range = -64 .. +64
668 // Find the unit cube containing the point
669 fl::u8 X = x>>8;
670
671 // Hash cube corner coordinates
672 fl::u8 A = NOISE_P(X);
673 fl::u8 AA = NOISE_P(A);
674 fl::u8 B = NOISE_P(X+1);
675 fl::u8 BA = NOISE_P(B);
676
677 // Get the relative position of the point in the cube
678 fl::u8 u = x;
679
680 // Get a signed version of the above for the grad function
681 fl::i8 xx = ((fl::u8)(x)>>1) & 0x7F;
682 fl::u8 N = 0x80;
683
684 u = EASE8( u);
685
686 fl::i8 ans = lerp7by8(grad8(NOISE_P(AA), xx), grad8(NOISE_P(BA), xx - N), u);
687
688 return ans;
689}
690
692 fl::i8 n = inoise8_raw(x); //-64..+64
693 n += 64; // 0..128
694 fl::u8 ans = qadd8(n,n); // 0..255
695 return ans;
696}
697
698
699// struct q44 {
700// uint8_t i:4;
701// uint8_t f:4;
702// fl::q44(uint8_t _i, uint8_t _f) {i=_i; f=_f; }
703// };
704
705// uint32_t mul44(uint32_t v, fl::q44 mulby44) {
706// return (v *mulby44.i) + ((v * mulby44.f) >> 4);
707// }
708//
709// uint16_t mul44_16(uint16_t v, fl::q44 mulby44) {
710// return (v *mulby44.i) + ((v * mulby44.f) >> 4);
711// }
712
713void fill_raw_noise8(fl::u8 *pData, fl::u8 num_points, fl::u8 octaves, fl::u16 x, int scale, fl::u16 time) FL_NO_EXCEPT {
714 fl::u32 _xx = x;
715 fl::u32 scx = scale;
716 for(int o = 0; o < octaves; ++o) {
717 for(int i = 0,xx=_xx; i < num_points; ++i, xx+=scx) {
718 pData[i] = qadd8(pData[i],inoise8(xx,time)>>o);
719 }
720
721 _xx <<= 1;
722 scx <<= 1;
723 }
724}
725
726void fill_raw_noise16into8(fl::u8 *pData, fl::u8 num_points, fl::u8 octaves, fl::u32 x, int scale, fl::u32 time) FL_NO_EXCEPT {
727 fl::u32 _xx = x;
728 fl::u32 scx = scale;
729 for(int o = 0; o < octaves; ++o) {
730 for(int i = 0,xx=_xx; i < num_points; ++i, xx+=scx) {
731 fl::u32 accum = (inoise16(xx,time))>>o;
732 accum += (pData[i]<<8);
733 if(accum > 65535) { accum = 65535; }
734 pData[i] = accum>>8;
735 }
736
737 _xx <<= 1;
738 scx <<= 1;
739 }
740}
741
756void fill_raw_2dnoise8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::q44 freq44, fract8 amplitude, int skip, fl::u16 x, fl::i16 scalex, fl::u16 y, fl::i16 scaley, fl::u16 time) FL_NO_EXCEPT {
757 if(octaves > 1) {
758 fill_raw_2dnoise8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, freq44 * scalex, y*freq44, freq44 * scaley, time);
759 } else {
760 // amplitude is always 255 on the lowest level
761 amplitude=255;
762 }
763
764 scalex *= skip;
765 scaley *= skip;
766
767 fract8 invamp = 255-amplitude;
768 fl::u16 xx = x;
769 for(int i = 0; i < height; ++i, y+=scaley) {
770 fl::u8 *pRow = pData + (i*width);
771 xx = x;
772 for(int j = 0; j < width; ++j, xx+=scalex) {
773 fl::u8 noise_base = inoise8(xx,y,time);
774 noise_base = (0x80 & noise_base) ? (noise_base - 127) : (127 - noise_base);
775 noise_base = scale8(noise_base<<1,amplitude);
776 if(skip == 1) {
777 pRow[j] = scale8(pRow[j],invamp) + noise_base;
778 } else {
779 for(int ii = i; ii<(i+skip) && ii<height; ++ii) {
780 fl::u8 *pRow = pData + (ii*width);
781 for(int jj=j; jj<(j+skip) && jj<width; ++jj) {
782 pRow[jj] = scale8(pRow[jj],invamp) + noise_base;
783 }
784 }
785 }
786 }
787 }
788}
789
790void fill_raw_2dnoise8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::u16 x, int scalex, fl::u16 y, int scaley, fl::u16 time) FL_NO_EXCEPT {
791 fill_raw_2dnoise8(pData, width, height, octaves, fl::q44(2,0), 128, 1, x, scalex, y, scaley, time);
792}
793
794void fill_raw_2dnoise16(fl::u16 *pData, int width, int height, fl::u8 octaves, fl::q88 freq88, fract16 amplitude, int skip, fl::u32 x, fl::i32 scalex, fl::u32 y, fl::i32 scaley, fl::u32 time) FL_NO_EXCEPT {
795 if(octaves > 1) {
796 fill_raw_2dnoise16(pData, width, height, octaves-1, freq88, amplitude, skip, x *freq88 , scalex *freq88, y * freq88, scaley * freq88, time);
797 } else {
798 // amplitude is always 255 on the lowest level
799 amplitude=65535;
800 }
801
802 scalex *= skip;
803 scaley *= skip;
804 fract16 invamp = 65535-amplitude;
805 for(int i = 0; i < height; i+=skip, y+=scaley) {
806 fl::u16 *pRow = pData + (i*width);
807 for(int j = 0,xx=x; j < width; j+=skip, xx+=scalex) {
808 fl::u16 noise_base = inoise16(xx,y,time);
809 noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base;
810 noise_base = scale16(noise_base<<1, amplitude);
811 if(skip==1) {
812 pRow[j] = scale16(pRow[j],invamp) + noise_base;
813 } else {
814 for(int ii = i; ii<(i+skip) && ii<height; ++ii) {
815 fl::u16 *pRow = pData + (ii*width);
816 for(int jj=j; jj<(j+skip) && jj<width; ++jj) {
817 pRow[jj] = scale16(pRow[jj],invamp) + noise_base;
818 }
819 }
820 }
821 }
822 }
823}
824
827fl::i32 nmin=11111110;
830fl::i32 nmax=0;
831
832void fill_raw_2dnoise16into8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::q44 freq44, fract8 amplitude, int skip, fl::u32 x, fl::i32 scalex, fl::u32 y, fl::i32 scaley, fl::u32 time) FL_NO_EXCEPT {
833 if(octaves > 1) {
834 fill_raw_2dnoise16into8(pData, width, height, octaves-1, freq44, amplitude, skip+1, x*freq44, scalex *freq44, y*freq44, scaley * freq44, time);
835 } else {
836 // amplitude is always 255 on the lowest level
837 amplitude=255;
838 }
839
840 scalex *= skip;
841 scaley *= skip;
842 fl::u32 xx;
843 fract8 invamp = 255-amplitude;
844 for(int i = 0; i < height; i+=skip, y+=scaley) {
845 fl::u8 *pRow = pData + (i*width);
846 xx = x;
847 for(int j = 0; j < width; j+=skip, xx+=scalex) {
848 fl::u16 noise_base = inoise16(xx,y,time);
849 noise_base = (0x8000 & noise_base) ? noise_base - (32767) : 32767 - noise_base;
850 noise_base = scale8(noise_base>>7,amplitude);
851 if(skip==1) {
852 pRow[j] = qadd8(scale8(pRow[j],invamp),noise_base);
853 } else {
854 for(int ii = i; ii<(i+skip) && ii<height; ++ii) {
855 fl::u8 *pRow = pData + (ii*width);
856 for(int jj=j; jj<(j+skip) && jj<width; ++jj) {
857 pRow[jj] = scale8(pRow[jj],invamp) + noise_base;
858 }
859 }
860 }
861 }
862 }
863}
864
865void fill_raw_2dnoise16into8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::u32 x, int scalex, fl::u32 y, int scaley, fl::u32 time) FL_NO_EXCEPT {
866 fill_raw_2dnoise16into8(pData, width, height, octaves, fl::q44(2,0), 171, 1, x, scalex, y, scaley, time);
867}
868
869void fill_noise8(CRGB *leds, int num_leds,
870 fl::u8 octaves, fl::u16 x, int scale,
871 fl::u8 hue_octaves, fl::u16 hue_x, int hue_scale,
872 fl::u16 time) FL_NO_EXCEPT {
873
874 if (num_leds <= 0) return;
875
876 for (int j = 0; j < num_leds; j += 255) {
877 const int LedsRemaining = num_leds - j;
878 const int LedsPer = LedsRemaining > 255 ? 255 : LedsRemaining; // limit to 255 max
879
880 if (LedsPer <= 0) continue;
881 FASTLED_STACK_ARRAY(fl::u8, V, LedsPer);
882 FASTLED_STACK_ARRAY(fl::u8, H, LedsPer);
883
884 fl::memset(V, 0, LedsPer);
885 fl::memset(H, 0, LedsPer);
886
887 fill_raw_noise8(V, LedsPer, octaves, x, scale, time);
888 fill_raw_noise8(H, LedsPer, hue_octaves, hue_x, hue_scale, time);
889
890 for (int i = 0; i < LedsPer; ++i) {
891 leds[i + j] = CHSV(H[i], 255, V[i]);
892 }
893 }
894}
895
896void fill_noise16(CRGB *leds, int num_leds,
897 fl::u8 octaves, fl::u16 x, int scale,
898 fl::u8 hue_octaves, fl::u16 hue_x, int hue_scale,
899 fl::u16 time, fl::u8 hue_shift) FL_NO_EXCEPT {
900
901 if (num_leds <= 0) return;
902
903 for (int j = 0; j < num_leds; j += 255) {
904 const int LedsRemaining = num_leds - j;
905 const int LedsPer = LedsRemaining > 255 ? 255 : LedsRemaining; // limit to 255 max
906 if (LedsPer <= 0) continue;
907 FASTLED_STACK_ARRAY(fl::u8, V, LedsPer);
908 FASTLED_STACK_ARRAY(fl::u8, H, LedsPer);
909
910 fl::memset(V, 0, LedsPer);
911 fl::memset(H, 0, LedsPer);
912
913 fill_raw_noise16into8(V, LedsPer, octaves, x, scale, time);
914 fill_raw_noise8(H, LedsPer, hue_octaves, hue_x, hue_scale, time);
915
916 for (int i = 0; i < LedsPer; ++i) {
917 leds[i + j] = CHSV(H[i] + hue_shift, 255, V[i]);
918 }
919 }
920}
921
922void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine,
923 fl::u8 octaves, fl::u16 x, int xscale, fl::u16 y, int yscale, fl::u16 time,
924 fl::u8 hue_octaves, fl::u16 hue_x, int hue_xscale, fl::u16 hue_y, fl::u16 hue_yscale,fl::u16 hue_time,bool blend) FL_NO_EXCEPT {
925 const size_t array_size = (size_t)height * width;
926 if (array_size <= 0) return;
927 FASTLED_STACK_ARRAY(fl::u8, V, array_size);
928 FASTLED_STACK_ARRAY(fl::u8, H, array_size);
929
930 fl::memset(V,0,height*width);
931 fl::memset(H,0,height*width);
932
933 fill_raw_2dnoise8((fl::u8*)V,width,height,octaves,x,xscale,y,yscale,time);
934 fill_raw_2dnoise8((fl::u8*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time);
935
936 int w1 = width-1;
937 int h1 = height-1;
938 for(int i = 0; i < height; ++i) {
939 int wb = i*width;
940 for(int j = 0; j < width; ++j) {
941 CRGB led(CHSV(H[(h1-i)*width + (w1-j)], 255, V[i*width + j]));
942
943 int pos = j;
944 if(serpentine && (i & 0x1)) {
945 pos = w1-j;
946 }
947
948 if(blend) {
949 // Safer blending using shift-and-add to avoid ambiguous operator+
950 leds[wb+pos] >>= 1;
951 leds[wb+pos] += (led >>= 1);
952 } else {
953 leds[wb+pos] = led;
954 }
955 }
956 }
957}
958
959
960void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine,
961 fl::u8 octaves, fl::u32 x, int xscale, fl::u32 y, int yscale, fl::u32 time,
962 fl::u8 hue_octaves, fl::u16 hue_x, int hue_xscale, fl::u16 hue_y, fl::u16 hue_yscale,fl::u16 hue_time, bool blend, fl::u16 hue_shift) FL_NO_EXCEPT {
963
964 FASTLED_STACK_ARRAY(fl::u8, V, height*width);
965 FASTLED_STACK_ARRAY(fl::u8, H, height*width);
966
967 fl::memset(V,0,height*width);
968 fl::memset(H,0,height*width);
969
970 fill_raw_2dnoise16into8((fl::u8*)V,width,height,octaves,fl::q44(2,0),171,1,x,xscale,y,yscale,time);
971 // fill_raw_2dnoise16into8((uint8_t*)V,width,height,octaves,x,xscale,y,yscale,time);
972 // fill_raw_2dnoise8((uint8_t*)V,width,height,hue_octaves,x,xscale,y,yscale,time);
973 fill_raw_2dnoise8((fl::u8*)H,width,height,hue_octaves,hue_x,hue_xscale,hue_y,hue_yscale,hue_time);
974
975
976 int w1 = width-1;
977 int h1 = height-1;
978 hue_shift >>= 8;
979
980 for(int i = 0; i < height; ++i) {
981 int wb = i*width;
982 for(int j = 0; j < width; ++j) {
983 CRGB led(CHSV(hue_shift + (H[(h1-i)*width + (w1-j)]), 196, V[i*width + j]));
984
985 int pos = j;
986 if(serpentine && (i & 0x1)) {
987 pos = w1-j;
988 }
989
990 if(blend) {
991 leds[wb+pos] >>= 1; leds[wb+pos] += (led>>=1);
992 } else {
993 leds[wb+pos] = led;
994 }
995 }
996 }
997}
998
CRGB leds[1]
int y
Definition simple.h:93
int x
Definition simple.h:92
uint8_t pos
Definition Blur.ino:11
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
fl::UISlider scale("Scale", 4,.1, 4,.1)
uint8_t hue_octaves
int yscale
uint8_t octaves
int xscale
int hue_scale
uint32_t hue_time
static const int H
Definition PerfDisc.ino:21
#define FASTLED_STACK_ARRAY(TYPE, NAME, SIZE)
Stack-allocated array with automatic zero-initialization.
Definition alloca.h:32
CRGB blend(const CRGB &p1, const CRGB &p2, fract8 amountOfP2) FL_NO_EXCEPT
#define FL_DISABLE_WARNING(warning)
#define FL_DISABLE_WARNING_PUSH
#define FL_DISABLE_WARNING_POP
static uint32_t t
Definition Luminova.h:55
#define FL_PROGMEM
PROGMEM keyword for storage.
Internal FastLED header for implementation files.
qfx< u16, 8, 8 > q88
A 8.8 integer (8 bits integer, 8 bits fraction)
Definition qfx.h:49
qfx< u8, 4, 4 > q44
A 4.4 integer (4 bits integer, 4 bits fraction)
Definition qfx.h:45
fl::hsv8 CHSV
Definition chsv.h:11
fl::CRGB CRGB
Definition crgb.h:25
void fill_raw_noise8(fl::u8 *pData, fl::u8 num_points, fl::u8 octaves, fl::u16 x, int scale, fl::u16 time) FL_NO_EXCEPT
Fill a 1D 8-bit buffer with noise, using inoise8()
void fill_raw_2dnoise16(fl::u16 *pData, int width, int height, fl::u8 octaves, fl::q88 freq88, fract16 amplitude, int skip, fl::u32 x, fl::i32 scalex, fl::u32 y, fl::i32 scaley, fl::u32 time) FL_NO_EXCEPT
Fill a 2D 16-bit buffer with noise, using inoise16()
void fill_noise8(CRGB *leds, int num_leds, fl::u8 octaves, fl::u16 x, int scale, fl::u8 hue_octaves, fl::u16 hue_x, int hue_scale, fl::u16 time) FL_NO_EXCEPT
Fill an LED array with random colors, using 8-bit noise.
void fill_2dnoise8(CRGB *leds, int width, int height, bool serpentine, fl::u8 octaves, fl::u16 x, int xscale, fl::u16 y, int yscale, fl::u16 time, fl::u8 hue_octaves, fl::u16 hue_x, int hue_xscale, fl::u16 hue_y, fl::u16 hue_yscale, fl::u16 hue_time, bool blend) FL_NO_EXCEPT
Fill an LED matrix with random colors, using 8-bit noise.
void fill_2dnoise16(CRGB *leds, int width, int height, bool serpentine, fl::u8 octaves, fl::u32 x, int xscale, fl::u32 y, int yscale, fl::u32 time, fl::u8 hue_octaves, fl::u16 hue_x, int hue_xscale, fl::u16 hue_y, fl::u16 hue_yscale, fl::u16 hue_time, bool blend, fl::u16 hue_shift) FL_NO_EXCEPT
Fill an LED matrix with random colors, using 16-bit noise.
void fill_raw_2dnoise8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::q44 freq44, fract8 amplitude, int skip, fl::u16 x, fl::i16 scalex, fl::u16 y, fl::i16 scaley, fl::u16 time) FL_NO_EXCEPT
Fill a 2D 8-bit buffer with noise, using inoise8()
void fill_raw_2dnoise16into8(fl::u8 *pData, int width, int height, fl::u8 octaves, fl::q44 freq44, fract8 amplitude, int skip, fl::u32 x, fl::i32 scalex, fl::u32 y, fl::i32 scaley, fl::u32 time) FL_NO_EXCEPT
Fill a 2D 8-bit buffer with noise, using inoise16()
void fill_raw_noise16into8(fl::u8 *pData, fl::u8 num_points, fl::u8 octaves, fl::u32 x, int scale, fl::u32 time) FL_NO_EXCEPT
Fill a 1D 8-bit buffer with noise, using inoise16()
void fill_noise16(CRGB *leds, int num_leds, fl::u8 octaves, fl::u16 x, int scale, fl::u8 hue_octaves, fl::u16 hue_x, int hue_scale, fl::u16 time, fl::u8 hue_shift) FL_NO_EXCEPT
Fill an LED array with random colors, using 16-bit noise.
fl::i8 inoise8_raw(fl::u16 x, fl::u16 y, fl::u16 z) FL_NO_EXCEPT
8-bit, fixed point implementation of Perlin's noise without scaling.
fl::u16 inoise16(fl::u32 x, fl::u32 y, fl::u32 z, fl::u32 t) FL_NO_EXCEPT
16-bit, fixed point implementation of Perlin's noise.
fl::i16 inoise16_raw(fl::u32 x, fl::u32 y, fl::u32 z) FL_NO_EXCEPT
16-bit, fixed point implementation of Perlin's noise without scaling.
fl::u8 inoise8(fl::u16 x, fl::u16 y, fl::u16 z) FL_NO_EXCEPT
8-Bit, fixed point implementation of Perlin's noise.
unsigned char u8
Definition stdint.h:131
u8 fract8
Fixed-Point Fractional Types.
Definition stdint.h:160
FASTLED_FORCE_INLINE void * memset(void *s, int c, size_t n) FL_NO_EXCEPT
Definition cstring.h:148
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
signed char i8
Definition stdint.h:130
u16 fract16
ANSI: unsigned _Fract.
Definition stdint.h:170
static fl::u8 const p[]
Definition noise.cpp.hpp:38
static fl::i8 lerp7by8(fl::i8 a, fl::i8 b, fract8 frac) FL_NO_EXCEPT
static fl::i16 grad16(fl::u8 hash, fl::i16 x, fl::i16 y, fl::i16 z) FL_NO_EXCEPT
fl::i32 nmax
Unused.
static fl::i8 selectBasedOnHashBit(fl::u8 hash, fl::u8 bitnumber, fl::i8 a, fl::i8 b) FL_NO_EXCEPT
fl::i32 nmin
Unused.
static fl::i8 grad8(fl::u8 hash, fl::i8 x, fl::i8 y, fl::i8 z) FL_NO_EXCEPT
#define NOISE_P(x)
Reads a single byte from the p array.
Definition noise.cpp.hpp:33
#define FL_NO_EXCEPT
fl::size size_t
Definition stdint.h:222