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 192 of file simplex.cpp.

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

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

+ Here is the call graph for this function: