FastLED 3.10.8
Loading...
Searching...
No Matches

◆ snoise16() [3/4]

fl::u16 snoise16 ( fl::u32 x,
fl::u32 y,
fl::u32 z )

Definition at line 197 of file simplex.cpp.hpp.

197 {
198 // Simple skewing factors for the 3D case
199 const u64 F3 = 1431655764; // .32: 0.333333333
200 const u64 G3 = 715827884; // .32: 0.166666667
201
202 // Skew the input space to determine which simplex cell we're in
203 fl::u32 s = (((u64)x + (u64)y + (u64)z) * F3) >> 32; // .12 + .32 = .12: Very nice and simple skew factor for 3D
204 fl::u32 i = ((x>>1) + (s>>1)) >> 11; // .0
205 fl::u32 j = ((y>>1) + (s>>1)) >> 11; // .0
206 fl::u32 k = ((z>>1) + (s>>1)) >> 11; // .0
207
208 u64 t = ((u64)i + (u64)j + (u64)k) * G3; // .32
209 u64 X0 = ((u64)i<<32) - t; // .32: Unskew the cell origin back to (x,y) space
210 u64 Y0 = ((u64)j<<32) - t; // .32
211 u64 Z0 = ((u64)k<<32) - t; // .32
212 fl::i32 x0 = ((u64)x<<2) - (X0>>18); // .14: The x,y distances from the cell origin
213 fl::i32 y0 = ((u64)y<<2) - (Y0>>18); // .14
214 fl::i32 z0 = ((u64)z<<2) - (Z0>>18); // .14
215
216 // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
217 // Determine which simplex we are in.
218 fl::u32 i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
219 fl::u32 i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
220
221 // This code would benefit from a backport from the GLSL version!
222 if (x0 >= y0) {
223 if (y0 >= z0) {
224 i1 = 1;
225 j1 = 0;
226 k1 = 0;
227 i2 = 1;
228 j2 = 1;
229 k2 = 0; // X Y Z order
230 } else if (x0 >= z0) {
231 i1 = 1;
232 j1 = 0;
233 k1 = 0;
234 i2 = 1;
235 j2 = 0;
236 k2 = 1; // X Z Y order
237 } else {
238 i1 = 0;
239 j1 = 0;
240 k1 = 1;
241 i2 = 1;
242 j2 = 0;
243 k2 = 1; // Z X Y order
244 }
245 } else { // x0<y0
246 if (y0 < z0) {
247 i1 = 0;
248 j1 = 0;
249 k1 = 1;
250 i2 = 0;
251 j2 = 1;
252 k2 = 1; // Z Y X order
253 } else if (x0 < z0) {
254 i1 = 0;
255 j1 = 1;
256 k1 = 0;
257 i2 = 0;
258 j2 = 1;
259 k2 = 1; // Y Z X order
260 } else {
261 i1 = 0;
262 j1 = 1;
263 k1 = 0;
264 i2 = 1;
265 j2 = 1;
266 k2 = 0; // Y X Z order
267 }
268 }
269
270 // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
271 // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
272 // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
273 // c = 1/6.
274
275 fl::i32 x1 = x0 - ((fl::i32)i1<<14) + ((fl::i32)(G3>>18)); // .14: Offsets for second corner in (x,y,z) coords
276 fl::i32 y1 = y0 - ((fl::i32)j1<<14) + ((fl::i32)(G3>>18)); // .14
277 fl::i32 z1 = z0 - ((fl::i32)k1<<14) + ((fl::i32)(G3>>18)); // .14
278 fl::i32 x2 = x0 - ((fl::i32)i2<<14) + ((fl::i32)(2*G3)>>18); // .14: Offsets for third corner in (x,y,z) coords
279 fl::i32 y2 = y0 - ((fl::i32)j2<<14) + ((fl::i32)(2*G3)>>18); // .14
280 fl::i32 z2 = z0 - ((fl::i32)k2<<14) + ((fl::i32)(2*G3)>>18); // .14
281 fl::i32 x3 = x0 - (1 << 14) + (fl::i32)((3*G3)>>18); // .14: Offsets for last corner in (x,y,z) coords
282 fl::i32 y3 = y0 - (1 << 14) + (fl::i32)((3*G3)>>18); // .14
283 fl::i32 z3 = z0 - (1 << 14) + (fl::i32)((3*G3)>>18); // .14
284
285 // Calculate the contribution from the four corners
286 fl::i32 n0 = 0, n1 = 0, n2 = 0, n3 = 0; // .30
287 const fl::i32 fix0_6 = 161061274; // .28: 0.6
288
289 fl::i32 t0 = (fix0_6 - x0*x0 - y0*y0 - z0*z0) >> 12; // .16
290 if (t0 > 0) {
291 t0 = (t0 * t0) >> 16; // .16
292 t0 = (t0 * t0) >> 16; // .16
293 // .16 * .14 = .30
294 n0 = t0 * grad(SIMPLEX_P((i+(fl::u32)SIMPLEX_P((j+(fl::u32)SIMPLEX_P(k&0xff))&0xff))&0xff), x0, y0, z0);
295 }
296
297 fl::i32 t1 = (fix0_6 - x1*x1 - y1*y1 - z1*z1) >> 12; // .16
298 if (t1 > 0) {
299 t1 = (t1 * t1) >> 16; // .16
300 t1 = (t1 * t1) >> 16; // .16
301 // .16 * .14 = .30
302 n1 = t1 * grad(SIMPLEX_P((i+i1+(fl::u32)SIMPLEX_P((j+j1+(fl::u32)SIMPLEX_P((k+k1)&0xff))&0xff))&0xff), x1, y1, z1);
303 }
304
305 fl::i32 t2 = (fix0_6 - x2*x2 - y2*y2 - z2*z2) >> 12; // .16
306 if (t2 > 0) {
307 t2 = (t2 * t2) >> 16; // .16
308 t2 = (t2 * t2) >> 16; // .16
309 // .16 * .14 = .30
310 n2 = t2 * grad(SIMPLEX_P((i+i2+(fl::u32)SIMPLEX_P((j+j2+(fl::u32)SIMPLEX_P((k+k2)&0xff))&0xff))&0xff), x2, y2, z2);
311 }
312
313 fl::i32 t3 = (fix0_6 - x3*x3 - y3*y3 - z3*z3) >> 12; // .16
314 if (t3 > 0) {
315 t3 = (t3 * t3) >> 16; // .16
316 t3 = (t3 * t3) >> 16; // .16
317 // .16 * .14 = .30
318 n3 = t3 * grad(SIMPLEX_P((i+1+(fl::u32)SIMPLEX_P((j+1+(fl::u32)SIMPLEX_P((k+1)&0xff))&0xff))&0xff), x3, y3, z3);
319 }
320
321 // Add contributions from each corner to get the final noise value.
322 // The result is scaled to stay just inside [-1,1]
323 fl::i32 n = n0 + n1 + n2 + n3; // .30
324 n = ((n >> 8) * 16748) >> 16 ; // fix scale to fit exactly in an int16
325 return (fl::u16)n + 0x8000;
326}
int y
Definition simple.h:93
int x
Definition simple.h:92
uint32_t z[NUM_LAYERS]
Definition Fire2023.h:93
static uint32_t t
Definition Luminova.h:55
#define SIMPLEX_P(x)
static fl::i32 grad(fl::u8 hash, fl::i32 x) FL_NO_EXCEPT
fl::u64 u64
Definition stdint.h:220

References FL_NO_EXCEPT, grad(), SIMPLEX_P, t, x, y, and z.

+ Here is the call graph for this function: