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

◆ snoise16() [3/4]

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

Definition at line 196 of file simplex.cpp.

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

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

+ Here is the call graph for this function: