Blender  V3.3
noise.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later AND BSD-3-Clause
2  * Copyright 2009-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved (BSD-3-Clause).
3  * 2011 Blender Foundation (GPL-2.0-or-later). */
4 
5 #include <algorithm>
6 #include <cmath>
7 #include <cstdint>
8 
9 #include "BLI_math_base_safe.h"
10 #include "BLI_math_vector.hh"
11 #include "BLI_noise.hh"
12 #include "BLI_utildefines.h"
13 
14 namespace blender::noise {
15 
16 /* -------------------------------------------------------------------- */
23 {
24  return (x << k) | (x >> (32 - k));
25 }
26 
28 {
29  a -= c;
30  a ^= hash_bit_rotate(c, 4);
31  c += b;
32  b -= a;
33  b ^= hash_bit_rotate(a, 6);
34  a += c;
35  c -= b;
36  c ^= hash_bit_rotate(b, 8);
37  b += a;
38  a -= c;
39  a ^= hash_bit_rotate(c, 16);
40  c += b;
41  b -= a;
42  b ^= hash_bit_rotate(a, 19);
43  a += c;
44  c -= b;
45  c ^= hash_bit_rotate(b, 4);
46  b += a;
47 }
48 
50 {
51  c ^= b;
52  c -= hash_bit_rotate(b, 14);
53  a ^= c;
54  a -= hash_bit_rotate(c, 11);
55  b ^= a;
56  b -= hash_bit_rotate(a, 25);
57  c ^= b;
58  c -= hash_bit_rotate(b, 16);
59  a ^= c;
60  a -= hash_bit_rotate(c, 4);
61  b ^= a;
62  b -= hash_bit_rotate(a, 14);
63  c ^= b;
64  c -= hash_bit_rotate(b, 24);
65 }
66 
68 {
69  uint32_t a, b, c;
70  a = b = c = 0xdeadbeef + (1 << 2) + 13;
71 
72  a += kx;
73  hash_bit_final(a, b, c);
74 
75  return c;
76 }
77 
79 {
80  uint32_t a, b, c;
81  a = b = c = 0xdeadbeef + (2 << 2) + 13;
82 
83  b += ky;
84  a += kx;
85  hash_bit_final(a, b, c);
86 
87  return c;
88 }
89 
91 {
92  uint32_t a, b, c;
93  a = b = c = 0xdeadbeef + (3 << 2) + 13;
94 
95  c += kz;
96  b += ky;
97  a += kx;
98  hash_bit_final(a, b, c);
99 
100  return c;
101 }
102 
104 {
105  uint32_t a, b, c;
106  a = b = c = 0xdeadbeef + (4 << 2) + 13;
107 
108  a += kx;
109  b += ky;
110  c += kz;
111  hash_bit_mix(a, b, c);
112 
113  a += kw;
114  hash_bit_final(a, b, c);
115 
116  return c;
117 }
118 
120 {
121  union {
122  uint32_t i;
123  float f;
124  } u;
125  u.f = f;
126  return u.i;
127 }
128 
130 {
131  return hash(float_as_uint(kx));
132 }
133 
135 {
136  return hash(float_as_uint(k.x), float_as_uint(k.y));
137 }
138 
140 {
141  return hash(float_as_uint(k.x), float_as_uint(k.y), float_as_uint(k.z));
142 }
143 
145 {
146  return hash(float_as_uint(k.x), float_as_uint(k.y), float_as_uint(k.z), float_as_uint(k.w));
147 }
148 
149 /* Hashing a number of uint32_t into a float in the range [0, 1]. */
150 
152 {
153  return static_cast<float>(k) / static_cast<float>(0xFFFFFFFFu);
154 }
155 
157 {
158  return uint_to_float_01(hash(kx));
159 }
160 
162 {
163  return uint_to_float_01(hash(kx, ky));
164 }
165 
167 {
168  return uint_to_float_01(hash(kx, ky, kz));
169 }
170 
172 {
173  return uint_to_float_01(hash(kx, ky, kz, kw));
174 }
175 
176 /* Hashing a number of floats into a float in the range [0, 1]. */
177 
178 float hash_float_to_float(float k)
179 {
180  return uint_to_float_01(hash_float(k));
181 }
182 
184 {
185  return uint_to_float_01(hash_float(k));
186 }
187 
189 {
190  return uint_to_float_01(hash_float(k));
191 }
192 
194 {
195  return uint_to_float_01(hash_float(k));
196 }
197 
199 {
200  return float2(hash_float_to_float(k), hash_float_to_float(float3(k.x, k.y, 1.0)));
201 }
202 
204 {
205  return float3(hash_float_to_float(k),
206  hash_float_to_float(float2(k, 1.0)),
207  hash_float_to_float(float2(k, 2.0)));
208 }
209 
211 {
212  return float3(hash_float_to_float(k),
213  hash_float_to_float(float3(k.x, k.y, 1.0)),
214  hash_float_to_float(float3(k.x, k.y, 2.0)));
215 }
216 
218 {
219  return float3(hash_float_to_float(k),
220  hash_float_to_float(float4(k.x, k.y, k.z, 1.0)),
221  hash_float_to_float(float4(k.x, k.y, k.z, 2.0)));
222 }
223 
225 {
226  return float3(hash_float_to_float(k),
227  hash_float_to_float(float4(k.z, k.x, k.w, k.y)),
228  hash_float_to_float(float4(k.w, k.z, k.y, k.x)));
229 }
230 
232 {
233  return float4(hash_float_to_float(k),
234  hash_float_to_float(float4(k.w, k.x, k.y, k.z)),
235  hash_float_to_float(float4(k.z, k.w, k.x, k.y)),
236  hash_float_to_float(float4(k.y, k.z, k.w, k.x)));
237 }
238 
241 /* -------------------------------------------------------------------- */
251 /* Linear Interpolation. */
252 BLI_INLINE float mix(float v0, float v1, float x)
253 {
254  return (1 - x) * v0 + x * v1;
255 }
256 
257 /* Bilinear Interpolation:
258  *
259  * v2 v3
260  * @ + + + + @ y
261  * + + ^
262  * + + |
263  * + + |
264  * @ + + + + @ @------> x
265  * v0 v1
266  *
267  */
268 BLI_INLINE float mix(float v0, float v1, float v2, float v3, float x, float y)
269 {
270  float x1 = 1.0 - x;
271  return (1.0 - y) * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x);
272 }
273 
274 /* Trilinear Interpolation:
275  *
276  * v6 v7
277  * @ + + + + + + @
278  * +\ +\
279  * + \ + \
280  * + \ + \
281  * + \ v4 + \ v5
282  * + @ + + + +++ + @ z
283  * + + + + y ^
284  * v2 @ + +++ + + + @ v3 + \ |
285  * \ + \ + \ |
286  * \ + \ + \|
287  * \ + \ + +---------> x
288  * \+ \+
289  * @ + + + + + + @
290  * v0 v1
291  */
292 BLI_INLINE float mix(float v0,
293  float v1,
294  float v2,
295  float v3,
296  float v4,
297  float v5,
298  float v6,
299  float v7,
300  float x,
301  float y,
302  float z)
303 {
304  float x1 = 1.0 - x;
305  float y1 = 1.0 - y;
306  float z1 = 1.0 - z;
307  return z1 * (y1 * (v0 * x1 + v1 * x) + y * (v2 * x1 + v3 * x)) +
308  z * (y1 * (v4 * x1 + v5 * x) + y * (v6 * x1 + v7 * x));
309 }
310 
311 /* Quadrilinear Interpolation. */
312 BLI_INLINE float mix(float v0,
313  float v1,
314  float v2,
315  float v3,
316  float v4,
317  float v5,
318  float v6,
319  float v7,
320  float v8,
321  float v9,
322  float v10,
323  float v11,
324  float v12,
325  float v13,
326  float v14,
327  float v15,
328  float x,
329  float y,
330  float z,
331  float w)
332 {
333  return mix(mix(v0, v1, v2, v3, v4, v5, v6, v7, x, y, z),
334  mix(v8, v9, v10, v11, v12, v13, v14, v15, x, y, z),
335  w);
336 }
337 
338 BLI_INLINE float fade(float t)
339 {
340  return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
341 }
342 
343 BLI_INLINE float negate_if(float value, uint32_t condition)
344 {
345  return (condition != 0u) ? -value : value;
346 }
347 
349 {
350  uint32_t h = hash & 15u;
351  float g = 1u + (h & 7u);
352  return negate_if(g, h & 8u) * x;
353 }
354 
355 BLI_INLINE float noise_grad(uint32_t hash, float x, float y)
356 {
357  uint32_t h = hash & 7u;
358  float u = h < 4u ? x : y;
359  float v = 2.0 * (h < 4u ? y : x);
360  return negate_if(u, h & 1u) + negate_if(v, h & 2u);
361 }
362 
363 BLI_INLINE float noise_grad(uint32_t hash, float x, float y, float z)
364 {
365  uint32_t h = hash & 15u;
366  float u = h < 8u ? x : y;
367  float vt = ELEM(h, 12u, 14u) ? x : z;
368  float v = h < 4u ? y : vt;
369  return negate_if(u, h & 1u) + negate_if(v, h & 2u);
370 }
371 
372 BLI_INLINE float noise_grad(uint32_t hash, float x, float y, float z, float w)
373 {
374  uint32_t h = hash & 31u;
375  float u = h < 24u ? x : y;
376  float v = h < 16u ? y : z;
377  float s = h < 8u ? z : w;
378  return negate_if(u, h & 1u) + negate_if(v, h & 2u) + negate_if(s, h & 4u);
379 }
380 
381 BLI_INLINE float floor_fraction(float x, int &i)
382 {
383  i = (int)x - ((x < 0) ? 1 : 0);
384  return x - i;
385 }
386 
387 BLI_INLINE float perlin_noise(float position)
388 {
389  int X;
390 
391  float fx = floor_fraction(position, X);
392 
393  float u = fade(fx);
394 
395  float r = mix(noise_grad(hash(X), fx), noise_grad(hash(X + 1), fx - 1.0), u);
396 
397  return r;
398 }
399 
401 {
402  int X, Y;
403 
404  float fx = floor_fraction(position.x, X);
405  float fy = floor_fraction(position.y, Y);
406 
407  float u = fade(fx);
408  float v = fade(fy);
409 
410  float r = mix(noise_grad(hash(X, Y), fx, fy),
411  noise_grad(hash(X + 1, Y), fx - 1.0, fy),
412  noise_grad(hash(X, Y + 1), fx, fy - 1.0),
413  noise_grad(hash(X + 1, Y + 1), fx - 1.0, fy - 1.0),
414  u,
415  v);
416 
417  return r;
418 }
419 
421 {
422  int X, Y, Z;
423 
424  float fx = floor_fraction(position.x, X);
425  float fy = floor_fraction(position.y, Y);
426  float fz = floor_fraction(position.z, Z);
427 
428  float u = fade(fx);
429  float v = fade(fy);
430  float w = fade(fz);
431 
432  float r = mix(noise_grad(hash(X, Y, Z), fx, fy, fz),
433  noise_grad(hash(X + 1, Y, Z), fx - 1, fy, fz),
434  noise_grad(hash(X, Y + 1, Z), fx, fy - 1, fz),
435  noise_grad(hash(X + 1, Y + 1, Z), fx - 1, fy - 1, fz),
436  noise_grad(hash(X, Y, Z + 1), fx, fy, fz - 1),
437  noise_grad(hash(X + 1, Y, Z + 1), fx - 1, fy, fz - 1),
438  noise_grad(hash(X, Y + 1, Z + 1), fx, fy - 1, fz - 1),
439  noise_grad(hash(X + 1, Y + 1, Z + 1), fx - 1, fy - 1, fz - 1),
440  u,
441  v,
442  w);
443 
444  return r;
445 }
446 
448 {
449  int X, Y, Z, W;
450 
451  float fx = floor_fraction(position.x, X);
452  float fy = floor_fraction(position.y, Y);
453  float fz = floor_fraction(position.z, Z);
454  float fw = floor_fraction(position.w, W);
455 
456  float u = fade(fx);
457  float v = fade(fy);
458  float t = fade(fz);
459  float s = fade(fw);
460 
461  float r = mix(
462  noise_grad(hash(X, Y, Z, W), fx, fy, fz, fw),
463  noise_grad(hash(X + 1, Y, Z, W), fx - 1.0, fy, fz, fw),
464  noise_grad(hash(X, Y + 1, Z, W), fx, fy - 1.0, fz, fw),
465  noise_grad(hash(X + 1, Y + 1, Z, W), fx - 1.0, fy - 1.0, fz, fw),
466  noise_grad(hash(X, Y, Z + 1, W), fx, fy, fz - 1.0, fw),
467  noise_grad(hash(X + 1, Y, Z + 1, W), fx - 1.0, fy, fz - 1.0, fw),
468  noise_grad(hash(X, Y + 1, Z + 1, W), fx, fy - 1.0, fz - 1.0, fw),
469  noise_grad(hash(X + 1, Y + 1, Z + 1, W), fx - 1.0, fy - 1.0, fz - 1.0, fw),
470  noise_grad(hash(X, Y, Z, W + 1), fx, fy, fz, fw - 1.0),
471  noise_grad(hash(X + 1, Y, Z, W + 1), fx - 1.0, fy, fz, fw - 1.0),
472  noise_grad(hash(X, Y + 1, Z, W + 1), fx, fy - 1.0, fz, fw - 1.0),
473  noise_grad(hash(X + 1, Y + 1, Z, W + 1), fx - 1.0, fy - 1.0, fz, fw - 1.0),
474  noise_grad(hash(X, Y, Z + 1, W + 1), fx, fy, fz - 1.0, fw - 1.0),
475  noise_grad(hash(X + 1, Y, Z + 1, W + 1), fx - 1.0, fy, fz - 1.0, fw - 1.0),
476  noise_grad(hash(X, Y + 1, Z + 1, W + 1), fx, fy - 1.0, fz - 1.0, fw - 1.0),
477  noise_grad(hash(X + 1, Y + 1, Z + 1, W + 1), fx - 1.0, fy - 1.0, fz - 1.0, fw - 1.0),
478  u,
479  v,
480  t,
481  s);
482 
483  return r;
484 }
485 
486 /* Signed versions of perlin noise in the range [-1, 1]. The scale values were computed
487  * experimentally by the OSL developers to remap the noise output to the correct range. */
488 
489 float perlin_signed(float position)
490 {
491  return perlin_noise(position) * 0.2500f;
492 }
493 
494 float perlin_signed(float2 position)
495 {
496  return perlin_noise(position) * 0.6616f;
497 }
498 
499 float perlin_signed(float3 position)
500 {
501  return perlin_noise(position) * 0.9820f;
502 }
503 
504 float perlin_signed(float4 position)
505 {
506  return perlin_noise(position) * 0.8344f;
507 }
508 
509 /* Positive versions of perlin noise in the range [0, 1]. */
510 
511 float perlin(float position)
512 {
513  return perlin_signed(position) / 2.0f + 0.5f;
514 }
515 
516 float perlin(float2 position)
517 {
518  return perlin_signed(position) / 2.0f + 0.5f;
519 }
520 
521 float perlin(float3 position)
522 {
523  return perlin_signed(position) / 2.0f + 0.5f;
524 }
525 
526 float perlin(float4 position)
527 {
528  return perlin_signed(position) / 2.0f + 0.5f;
529 }
530 
531 /* Positive fractal perlin noise. */
532 
533 template<typename T> float perlin_fractal_template(T position, float octaves, float roughness)
534 {
535  float fscale = 1.0f;
536  float amp = 1.0f;
537  float maxamp = 0.0f;
538  float sum = 0.0f;
539  octaves = CLAMPIS(octaves, 0.0f, 15.0f);
540  int n = static_cast<int>(octaves);
541  for (int i = 0; i <= n; i++) {
542  float t = perlin(fscale * position);
543  sum += t * amp;
544  maxamp += amp;
545  amp *= CLAMPIS(roughness, 0.0f, 1.0f);
546  fscale *= 2.0f;
547  }
548  float rmd = octaves - std::floor(octaves);
549  if (rmd == 0.0f) {
550  return sum / maxamp;
551  }
552 
553  float t = perlin(fscale * position);
554  float sum2 = sum + t * amp;
555  sum /= maxamp;
556  sum2 /= maxamp + amp;
557  return (1.0f - rmd) * sum + rmd * sum2;
558 }
559 
560 float perlin_fractal(float position, float octaves, float roughness)
561 {
562  return perlin_fractal_template(position, octaves, roughness);
563 }
564 
565 float perlin_fractal(float2 position, float octaves, float roughness)
566 {
567  return perlin_fractal_template(position, octaves, roughness);
568 }
569 
570 float perlin_fractal(float3 position, float octaves, float roughness)
571 {
572  return perlin_fractal_template(position, octaves, roughness);
573 }
574 
575 float perlin_fractal(float4 position, float octaves, float roughness)
576 {
577  return perlin_fractal_template(position, octaves, roughness);
578 }
579 
580 /* The following offset functions generate random offsets to be added to
581  * positions to act as a seed since the noise functions don't have seed values.
582  * The offset's components are in the range [100, 200], not too high to cause
583  * bad precision and not too small to be noticeable. We use float seed because
584  * OSL only supports float hashes and we need to maintain compatibility with it.
585  */
586 
588 {
589  return 100.0f + hash_float_to_float(seed) * 100.0f;
590 }
591 
593 {
594  return float2(100.0f + hash_float_to_float(float2(seed, 0.0f)) * 100.0f,
595  100.0f + hash_float_to_float(float2(seed, 1.0f)) * 100.0f);
596 }
597 
599 {
600  return float3(100.0f + hash_float_to_float(float2(seed, 0.0f)) * 100.0f,
601  100.0f + hash_float_to_float(float2(seed, 1.0f)) * 100.0f,
602  100.0f + hash_float_to_float(float2(seed, 2.0f)) * 100.0f);
603 }
604 
606 {
607  return float4(100.0f + hash_float_to_float(float2(seed, 0.0f)) * 100.0f,
608  100.0f + hash_float_to_float(float2(seed, 1.0f)) * 100.0f,
609  100.0f + hash_float_to_float(float2(seed, 2.0f)) * 100.0f,
610  100.0f + hash_float_to_float(float2(seed, 3.0f)) * 100.0f);
611 }
612 
613 /* Perlin noises to be added to the position to distort other noises. */
614 
615 BLI_INLINE float perlin_distortion(float position, float strength)
616 {
617  return perlin_signed(position + random_float_offset(0.0)) * strength;
618 }
619 
620 BLI_INLINE float2 perlin_distortion(float2 position, float strength)
621 {
622  return float2(perlin_signed(position + random_float2_offset(0.0f)) * strength,
623  perlin_signed(position + random_float2_offset(1.0f)) * strength);
624 }
625 
626 BLI_INLINE float3 perlin_distortion(float3 position, float strength)
627 {
628  return float3(perlin_signed(position + random_float3_offset(0.0f)) * strength,
629  perlin_signed(position + random_float3_offset(1.0f)) * strength,
630  perlin_signed(position + random_float3_offset(2.0f)) * strength);
631 }
632 
633 BLI_INLINE float4 perlin_distortion(float4 position, float strength)
634 {
635  return float4(perlin_signed(position + random_float4_offset(0.0f)) * strength,
636  perlin_signed(position + random_float4_offset(1.0f)) * strength,
637  perlin_signed(position + random_float4_offset(2.0f)) * strength,
638  perlin_signed(position + random_float4_offset(3.0f)) * strength);
639 }
640 
641 /* Positive distorted fractal perlin noise. */
642 
643 float perlin_fractal_distorted(float position, float octaves, float roughness, float distortion)
644 {
645  position += perlin_distortion(position, distortion);
646  return perlin_fractal(position, octaves, roughness);
647 }
648 
649 float perlin_fractal_distorted(float2 position, float octaves, float roughness, float distortion)
650 {
651  position += perlin_distortion(position, distortion);
652  return perlin_fractal(position, octaves, roughness);
653 }
654 
655 float perlin_fractal_distorted(float3 position, float octaves, float roughness, float distortion)
656 {
657  position += perlin_distortion(position, distortion);
658  return perlin_fractal(position, octaves, roughness);
659 }
660 
661 float perlin_fractal_distorted(float4 position, float octaves, float roughness, float distortion)
662 {
663  position += perlin_distortion(position, distortion);
664  return perlin_fractal(position, octaves, roughness);
665 }
666 
667 /* Positive distorted fractal perlin noise that outputs a float3. The arbitrary seeds are for
668  * compatibility with shading functions. */
669 
671  float octaves,
672  float roughness,
673  float distortion)
674 {
675  position += perlin_distortion(position, distortion);
676  return float3(perlin_fractal(position, octaves, roughness),
677  perlin_fractal(position + random_float_offset(1.0f), octaves, roughness),
678  perlin_fractal(position + random_float_offset(2.0f), octaves, roughness));
679 }
680 
682  float octaves,
683  float roughness,
684  float distortion)
685 {
686  position += perlin_distortion(position, distortion);
687  return float3(perlin_fractal(position, octaves, roughness),
688  perlin_fractal(position + random_float2_offset(2.0f), octaves, roughness),
689  perlin_fractal(position + random_float2_offset(3.0f), octaves, roughness));
690 }
691 
693  float octaves,
694  float roughness,
695  float distortion)
696 {
697  position += perlin_distortion(position, distortion);
698  return float3(perlin_fractal(position, octaves, roughness),
699  perlin_fractal(position + random_float3_offset(3.0f), octaves, roughness),
700  perlin_fractal(position + random_float3_offset(4.0f), octaves, roughness));
701 }
702 
704  float octaves,
705  float roughness,
706  float distortion)
707 {
708  position += perlin_distortion(position, distortion);
709  return float3(perlin_fractal(position, octaves, roughness),
710  perlin_fractal(position + random_float4_offset(4.0f), octaves, roughness),
711  perlin_fractal(position + random_float4_offset(5.0f), octaves, roughness));
712 }
713 
716 /* -------------------------------------------------------------------- */
720 float musgrave_fBm(const float co,
721  const float H,
722  const float lacunarity,
723  const float octaves_unclamped)
724 {
725  /* From "Texturing and Modelling: A procedural approach". */
726 
727  float p = co;
728  float value = 0.0f;
729  float pwr = 1.0f;
730  const float pwHL = std::pow(lacunarity, -H);
731  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
732 
733  for (int i = 0; i < (int)octaves; i++) {
734  value += perlin_signed(p) * pwr;
735  pwr *= pwHL;
736  p *= lacunarity;
737  }
738 
739  float rmd = octaves - floorf(octaves);
740  if (rmd != 0.0f) {
741  value += rmd * perlin_signed(p) * pwr;
742  }
743 
744  return value;
745 }
746 
747 float musgrave_multi_fractal(const float co,
748  const float H,
749  const float lacunarity,
750  const float octaves_unclamped)
751 {
752  float p = co;
753  float value = 1.0f;
754  float pwr = 1.0f;
755  const float pwHL = std::pow(lacunarity, -H);
756  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
757 
758  for (int i = 0; i < (int)octaves; i++) {
759  value *= (pwr * perlin_signed(p) + 1.0f);
760  pwr *= pwHL;
761  p *= lacunarity;
762  }
763 
764  const float rmd = octaves - floorf(octaves);
765  if (rmd != 0.0f) {
766  value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
767  }
768 
769  return value;
770 }
771 
772 float musgrave_hetero_terrain(const float co,
773  const float H,
774  const float lacunarity,
775  const float octaves_unclamped,
776  const float offset)
777 {
778  float p = co;
779  const float pwHL = std::pow(lacunarity, -H);
780  float pwr = pwHL;
781  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
782 
783  /* First unscaled octave of function; later octaves are scaled. */
784  float value = offset + perlin_signed(p);
785  p *= lacunarity;
786 
787  for (int i = 1; i < (int)octaves; i++) {
788  float increment = (perlin_signed(p) + offset) * pwr * value;
789  value += increment;
790  pwr *= pwHL;
791  p *= lacunarity;
792  }
793 
794  const float rmd = octaves - floorf(octaves);
795  if (rmd != 0.0f) {
796  float increment = (perlin_signed(p) + offset) * pwr * value;
797  value += rmd * increment;
798  }
799 
800  return value;
801 }
802 
803 float musgrave_hybrid_multi_fractal(const float co,
804  const float H,
805  const float lacunarity,
806  const float octaves_unclamped,
807  const float offset,
808  const float gain)
809 {
810  float p = co;
811  const float pwHL = std::pow(lacunarity, -H);
812 
813  float pwr = 1.0f;
814  float value = 0.0f;
815  float weight = 1.0f;
816 
817  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
818 
819  for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
820  if (weight > 1.0f) {
821  weight = 1.0f;
822  }
823 
824  float signal = (perlin_signed(p) + offset) * pwr;
825  pwr *= pwHL;
826  value += weight * signal;
827  weight *= gain * signal;
828  p *= lacunarity;
829  }
830 
831  const float rmd = octaves - floorf(octaves);
832  if ((rmd != 0.0f) && (weight > 0.001f)) {
833  if (weight > 1.0f) {
834  weight = 1.0f;
835  }
836  float signal = (perlin_signed(p) + offset) * pwr;
837  value += rmd * weight * signal;
838  }
839 
840  return value;
841 }
842 
843 float musgrave_ridged_multi_fractal(const float co,
844  const float H,
845  const float lacunarity,
846  const float octaves_unclamped,
847  const float offset,
848  const float gain)
849 {
850  float p = co;
851  const float pwHL = std::pow(lacunarity, -H);
852  float pwr = pwHL;
853 
854  float signal = offset - std::abs(perlin_signed(p));
855  signal *= signal;
856  float value = signal;
857  float weight = 1.0f;
858 
859  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
860 
861  for (int i = 1; i < (int)octaves; i++) {
862  p *= lacunarity;
863  weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
864  signal = offset - std::abs(perlin_signed(p));
865  signal *= signal;
866  signal *= weight;
867  value += signal * pwr;
868  pwr *= pwHL;
869  }
870 
871  return value;
872 }
873 
874 float musgrave_fBm(const float2 co,
875  const float H,
876  const float lacunarity,
877  const float octaves_unclamped)
878 {
879  /* From "Texturing and Modelling: A procedural approach". */
880 
881  float2 p = co;
882  float value = 0.0f;
883  float pwr = 1.0f;
884  const float pwHL = std::pow(lacunarity, -H);
885  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
886 
887  for (int i = 0; i < (int)octaves; i++) {
888  value += perlin_signed(p) * pwr;
889  pwr *= pwHL;
890  p *= lacunarity;
891  }
892 
893  const float rmd = octaves - floorf(octaves);
894  if (rmd != 0.0f) {
895  value += rmd * perlin_signed(p) * pwr;
896  }
897 
898  return value;
899 }
900 
902  const float H,
903  const float lacunarity,
904  const float octaves_unclamped)
905 {
906  float2 p = co;
907  float value = 1.0f;
908  float pwr = 1.0f;
909  const float pwHL = std::pow(lacunarity, -H);
910  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
911 
912  for (int i = 0; i < (int)octaves; i++) {
913  value *= (pwr * perlin_signed(p) + 1.0f);
914  pwr *= pwHL;
915  p *= lacunarity;
916  }
917 
918  const float rmd = octaves - floorf(octaves);
919  if (rmd != 0.0f) {
920  value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
921  }
922 
923  return value;
924 }
925 
927  const float H,
928  const float lacunarity,
929  const float octaves_unclamped,
930  const float offset)
931 {
932  float2 p = co;
933  const float pwHL = std::pow(lacunarity, -H);
934  float pwr = pwHL;
935 
936  /* First unscaled octave of function; later octaves are scaled. */
937  float value = offset + perlin_signed(p);
938  p *= lacunarity;
939 
940  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
941 
942  for (int i = 1; i < (int)octaves; i++) {
943  float increment = (perlin_signed(p) + offset) * pwr * value;
944  value += increment;
945  pwr *= pwHL;
946  p *= lacunarity;
947  }
948 
949  const float rmd = octaves - floorf(octaves);
950  if (rmd != 0.0f) {
951  float increment = (perlin_signed(p) + offset) * pwr * value;
952  value += rmd * increment;
953  }
954 
955  return value;
956 }
957 
959  const float H,
960  const float lacunarity,
961  const float octaves_unclamped,
962  const float offset,
963  const float gain)
964 {
965  float2 p = co;
966  const float pwHL = std::pow(lacunarity, -H);
967 
968  float pwr = 1.0f;
969  float value = 0.0f;
970  float weight = 1.0f;
971 
972  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
973 
974  for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
975  if (weight > 1.0f) {
976  weight = 1.0f;
977  }
978 
979  float signal = (perlin_signed(p) + offset) * pwr;
980  pwr *= pwHL;
981  value += weight * signal;
982  weight *= gain * signal;
983  p *= lacunarity;
984  }
985 
986  const float rmd = octaves - floorf(octaves);
987  if ((rmd != 0.0f) && (weight > 0.001f)) {
988  if (weight > 1.0f) {
989  weight = 1.0f;
990  }
991  float signal = (perlin_signed(p) + offset) * pwr;
992  value += rmd * weight * signal;
993  }
994 
995  return value;
996 }
997 
999  const float H,
1000  const float lacunarity,
1001  const float octaves_unclamped,
1002  const float offset,
1003  const float gain)
1004 {
1005  float2 p = co;
1006  const float pwHL = std::pow(lacunarity, -H);
1007  float pwr = pwHL;
1008 
1009  float signal = offset - std::abs(perlin_signed(p));
1010  signal *= signal;
1011  float value = signal;
1012  float weight = 1.0f;
1013 
1014  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1015 
1016  for (int i = 1; i < (int)octaves; i++) {
1017  p *= lacunarity;
1018  weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
1019  signal = offset - std::abs(perlin_signed(p));
1020  signal *= signal;
1021  signal *= weight;
1022  value += signal * pwr;
1023  pwr *= pwHL;
1024  }
1025 
1026  return value;
1027 }
1028 
1029 float musgrave_fBm(const float3 co,
1030  const float H,
1031  const float lacunarity,
1032  const float octaves_unclamped)
1033 {
1034  /* From "Texturing and Modelling: A procedural approach". */
1035 
1036  float3 p = co;
1037  float value = 0.0f;
1038  float pwr = 1.0f;
1039  const float pwHL = std::pow(lacunarity, -H);
1040 
1041  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1042 
1043  for (int i = 0; i < (int)octaves; i++) {
1044  value += perlin_signed(p) * pwr;
1045  pwr *= pwHL;
1046  p *= lacunarity;
1047  }
1048 
1049  const float rmd = octaves - floorf(octaves);
1050  if (rmd != 0.0f) {
1051  value += rmd * perlin_signed(p) * pwr;
1052  }
1053 
1054  return value;
1055 }
1056 
1058  const float H,
1059  const float lacunarity,
1060  const float octaves_unclamped)
1061 {
1062  float3 p = co;
1063  float value = 1.0f;
1064  float pwr = 1.0f;
1065  const float pwHL = std::pow(lacunarity, -H);
1066 
1067  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1068 
1069  for (int i = 0; i < (int)octaves; i++) {
1070  value *= (pwr * perlin_signed(p) + 1.0f);
1071  pwr *= pwHL;
1072  p *= lacunarity;
1073  }
1074 
1075  const float rmd = octaves - floorf(octaves);
1076  if (rmd != 0.0f) {
1077  value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
1078  }
1079 
1080  return value;
1081 }
1082 
1084  const float H,
1085  const float lacunarity,
1086  const float octaves_unclamped,
1087  const float offset)
1088 {
1089  float3 p = co;
1090  const float pwHL = std::pow(lacunarity, -H);
1091  float pwr = pwHL;
1092 
1093  /* first unscaled octave of function; later octaves are scaled */
1094  float value = offset + perlin_signed(p);
1095  p *= lacunarity;
1096 
1097  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1098 
1099  for (int i = 1; i < (int)octaves; i++) {
1100  float increment = (perlin_signed(p) + offset) * pwr * value;
1101  value += increment;
1102  pwr *= pwHL;
1103  p *= lacunarity;
1104  }
1105 
1106  const float rmd = octaves - floorf(octaves);
1107  if (rmd != 0.0f) {
1108  float increment = (perlin_signed(p) + offset) * pwr * value;
1109  value += rmd * increment;
1110  }
1111 
1112  return value;
1113 }
1114 
1116  const float H,
1117  const float lacunarity,
1118  const float octaves_unclamped,
1119  const float offset,
1120  const float gain)
1121 {
1122  float3 p = co;
1123  const float pwHL = std::pow(lacunarity, -H);
1124 
1125  float pwr = 1.0f;
1126  float value = 0.0f;
1127  float weight = 1.0f;
1128 
1129  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1130 
1131  for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
1132  if (weight > 1.0f) {
1133  weight = 1.0f;
1134  }
1135 
1136  float signal = (perlin_signed(p) + offset) * pwr;
1137  pwr *= pwHL;
1138  value += weight * signal;
1139  weight *= gain * signal;
1140  p *= lacunarity;
1141  }
1142 
1143  const float rmd = octaves - floorf(octaves);
1144  if ((rmd != 0.0f) && (weight > 0.001f)) {
1145  if (weight > 1.0f) {
1146  weight = 1.0f;
1147  }
1148  float signal = (perlin_signed(p) + offset) * pwr;
1149  value += rmd * weight * signal;
1150  }
1151 
1152  return value;
1153 }
1154 
1156  const float H,
1157  const float lacunarity,
1158  const float octaves_unclamped,
1159  const float offset,
1160  const float gain)
1161 {
1162  float3 p = co;
1163  const float pwHL = std::pow(lacunarity, -H);
1164  float pwr = pwHL;
1165 
1166  float signal = offset - std::abs(perlin_signed(p));
1167  signal *= signal;
1168  float value = signal;
1169  float weight = 1.0f;
1170 
1171  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1172 
1173  for (int i = 1; i < (int)octaves; i++) {
1174  p *= lacunarity;
1175  weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
1176  signal = offset - std::abs(perlin_signed(p));
1177  signal *= signal;
1178  signal *= weight;
1179  value += signal * pwr;
1180  pwr *= pwHL;
1181  }
1182 
1183  return value;
1184 }
1185 
1186 float musgrave_fBm(const float4 co,
1187  const float H,
1188  const float lacunarity,
1189  const float octaves_unclamped)
1190 {
1191  /* From "Texturing and Modelling: A procedural approach". */
1192 
1193  float4 p = co;
1194  float value = 0.0f;
1195  float pwr = 1.0f;
1196  const float pwHL = std::pow(lacunarity, -H);
1197 
1198  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1199 
1200  for (int i = 0; i < (int)octaves; i++) {
1201  value += perlin_signed(p) * pwr;
1202  pwr *= pwHL;
1203  p *= lacunarity;
1204  }
1205 
1206  const float rmd = octaves - floorf(octaves);
1207  if (rmd != 0.0f) {
1208  value += rmd * perlin_signed(p) * pwr;
1209  }
1210 
1211  return value;
1212 }
1213 
1215  const float H,
1216  const float lacunarity,
1217  const float octaves_unclamped)
1218 {
1219  float4 p = co;
1220  float value = 1.0f;
1221  float pwr = 1.0f;
1222  const float pwHL = std::pow(lacunarity, -H);
1223 
1224  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1225 
1226  for (int i = 0; i < (int)octaves; i++) {
1227  value *= (pwr * perlin_signed(p) + 1.0f);
1228  pwr *= pwHL;
1229  p *= lacunarity;
1230  }
1231 
1232  const float rmd = octaves - floorf(octaves);
1233  if (rmd != 0.0f) {
1234  value *= (rmd * pwr * perlin_signed(p) + 1.0f); /* correct? */
1235  }
1236 
1237  return value;
1238 }
1239 
1241  const float H,
1242  const float lacunarity,
1243  const float octaves_unclamped,
1244  const float offset)
1245 {
1246  float4 p = co;
1247  const float pwHL = std::pow(lacunarity, -H);
1248  float pwr = pwHL;
1249 
1250  /* first unscaled octave of function; later octaves are scaled */
1251  float value = offset + perlin_signed(p);
1252  p *= lacunarity;
1253 
1254  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1255 
1256  for (int i = 1; i < (int)octaves; i++) {
1257  float increment = (perlin_signed(p) + offset) * pwr * value;
1258  value += increment;
1259  pwr *= pwHL;
1260  p *= lacunarity;
1261  }
1262 
1263  const float rmd = octaves - floorf(octaves);
1264  if (rmd != 0.0f) {
1265  float increment = (perlin_signed(p) + offset) * pwr * value;
1266  value += rmd * increment;
1267  }
1268 
1269  return value;
1270 }
1271 
1273  const float H,
1274  const float lacunarity,
1275  const float octaves_unclamped,
1276  const float offset,
1277  const float gain)
1278 {
1279  float4 p = co;
1280  const float pwHL = std::pow(lacunarity, -H);
1281 
1282  float pwr = 1.0f;
1283  float value = 0.0f;
1284  float weight = 1.0f;
1285 
1286  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1287 
1288  for (int i = 0; (weight > 0.001f) && (i < (int)octaves); i++) {
1289  if (weight > 1.0f) {
1290  weight = 1.0f;
1291  }
1292 
1293  float signal = (perlin_signed(p) + offset) * pwr;
1294  pwr *= pwHL;
1295  value += weight * signal;
1296  weight *= gain * signal;
1297  p *= lacunarity;
1298  }
1299 
1300  const float rmd = octaves - floorf(octaves);
1301  if ((rmd != 0.0f) && (weight > 0.001f)) {
1302  if (weight > 1.0f) {
1303  weight = 1.0f;
1304  }
1305  float signal = (perlin_signed(p) + offset) * pwr;
1306  value += rmd * weight * signal;
1307  }
1308 
1309  return value;
1310 }
1311 
1313  const float H,
1314  const float lacunarity,
1315  const float octaves_unclamped,
1316  const float offset,
1317  const float gain)
1318 {
1319  float4 p = co;
1320  const float pwHL = std::pow(lacunarity, -H);
1321  float pwr = pwHL;
1322 
1323  float signal = offset - std::abs(perlin_signed(p));
1324  signal *= signal;
1325  float value = signal;
1326  float weight = 1.0f;
1327 
1328  const float octaves = CLAMPIS(octaves_unclamped, 0.0f, 15.0f);
1329 
1330  for (int i = 1; i < (int)octaves; i++) {
1331  p *= lacunarity;
1332  weight = CLAMPIS(signal * gain, 0.0f, 1.0f);
1333  signal = offset - std::abs(perlin_signed(p));
1334  signal *= signal;
1335  signal *= weight;
1336  value += signal * pwr;
1337  pwr *= pwHL;
1338  }
1339 
1340  return value;
1341 }
1342 
1345 /* -------------------------------------------------------------------- */
1365 /* **** 1D Voronoi **** */
1366 
1367 /* Ensure to align with DNA. */
1368 enum {
1373 };
1374 
1375 BLI_INLINE float voronoi_distance(const float a, const float b)
1376 {
1377  return std::abs(b - a);
1378 }
1379 
1381  const float w, const float randomness, float *r_distance, float3 *r_color, float *r_w)
1382 {
1383  const float cellPosition = floorf(w);
1384  const float localPosition = w - cellPosition;
1385 
1386  float minDistance = 8.0f;
1387  float targetOffset = 0.0f;
1388  float targetPosition = 0.0f;
1389  for (int i = -1; i <= 1; i++) {
1390  const float cellOffset = i;
1391  const float pointPosition = cellOffset +
1392  hash_float_to_float(cellPosition + cellOffset) * randomness;
1393  const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
1394  if (distanceToPoint < minDistance) {
1395  targetOffset = cellOffset;
1396  minDistance = distanceToPoint;
1397  targetPosition = pointPosition;
1398  }
1399  }
1400  if (r_distance != nullptr) {
1401  *r_distance = minDistance;
1402  }
1403  if (r_color != nullptr) {
1404  *r_color = hash_float_to_float3(cellPosition + targetOffset);
1405  }
1406  if (r_w != nullptr) {
1407  *r_w = targetPosition + cellPosition;
1408  }
1409 }
1410 
1411 void voronoi_smooth_f1(const float w,
1412  const float smoothness,
1413  const float randomness,
1414  float *r_distance,
1415  float3 *r_color,
1416  float *r_w)
1417 {
1418  const float cellPosition = floorf(w);
1419  const float localPosition = w - cellPosition;
1420  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
1421 
1422  float smoothDistance = 8.0f;
1423  float smoothPosition = 0.0f;
1424  float3 smoothColor = float3(0.0f, 0.0f, 0.0f);
1425  for (int i = -2; i <= 2; i++) {
1426  const float cellOffset = i;
1427  const float pointPosition = cellOffset +
1428  hash_float_to_float(cellPosition + cellOffset) * randomness;
1429  const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
1430  const float h = smoothstep(
1431  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness_clamped);
1432  float correctionFactor = smoothness * h * (1.0f - h);
1433  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
1434  if (r_color != nullptr || r_w != nullptr) {
1435  correctionFactor /= 1.0f + 3.0f * smoothness;
1436  if (r_color != nullptr) {
1437  const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
1438  smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
1439  }
1440  if (r_w != nullptr) {
1441  smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
1442  }
1443  }
1444  }
1445  if (r_distance != nullptr) {
1446  *r_distance = smoothDistance;
1447  }
1448  if (r_color != nullptr) {
1449  *r_color = smoothColor;
1450  }
1451  if (r_w != nullptr) {
1452  *r_w = cellPosition + smoothPosition;
1453  }
1454 }
1455 
1457  const float w, const float randomness, float *r_distance, float3 *r_color, float *r_w)
1458 {
1459  const float cellPosition = floorf(w);
1460  const float localPosition = w - cellPosition;
1461 
1462  float distanceF1 = 8.0f;
1463  float distanceF2 = 8.0f;
1464  float offsetF1 = 0.0f;
1465  float positionF1 = 0.0f;
1466  float offsetF2 = 0.0f;
1467  float positionF2 = 0.0f;
1468  for (int i = -1; i <= 1; i++) {
1469  const float cellOffset = i;
1470  const float pointPosition = cellOffset +
1471  hash_float_to_float(cellPosition + cellOffset) * randomness;
1472  const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
1473  if (distanceToPoint < distanceF1) {
1474  distanceF2 = distanceF1;
1475  distanceF1 = distanceToPoint;
1476  offsetF2 = offsetF1;
1477  offsetF1 = cellOffset;
1478  positionF2 = positionF1;
1479  positionF1 = pointPosition;
1480  }
1481  else if (distanceToPoint < distanceF2) {
1482  distanceF2 = distanceToPoint;
1483  offsetF2 = cellOffset;
1484  positionF2 = pointPosition;
1485  }
1486  }
1487  if (r_distance != nullptr) {
1488  *r_distance = distanceF2;
1489  }
1490  if (r_color != nullptr) {
1491  *r_color = hash_float_to_float3(cellPosition + offsetF2);
1492  }
1493  if (r_w != nullptr) {
1494  *r_w = positionF2 + cellPosition;
1495  }
1496 }
1497 
1498 void voronoi_distance_to_edge(const float w, const float randomness, float *r_distance)
1499 {
1500  const float cellPosition = floorf(w);
1501  const float localPosition = w - cellPosition;
1502 
1503  const float midPointPosition = hash_float_to_float(cellPosition) * randomness;
1504  const float leftPointPosition = -1.0f + hash_float_to_float(cellPosition - 1.0f) * randomness;
1505  const float rightPointPosition = 1.0f + hash_float_to_float(cellPosition + 1.0f) * randomness;
1506  const float distanceToMidLeft = std::abs((midPointPosition + leftPointPosition) / 2.0f -
1507  localPosition);
1508  const float distanceToMidRight = std::abs((midPointPosition + rightPointPosition) / 2.0f -
1509  localPosition);
1510 
1511  *r_distance = std::min(distanceToMidLeft, distanceToMidRight);
1512 }
1513 
1514 void voronoi_n_sphere_radius(const float w, const float randomness, float *r_radius)
1515 {
1516  const float cellPosition = floorf(w);
1517  const float localPosition = w - cellPosition;
1518 
1519  float closestPoint = 0.0f;
1520  float closestPointOffset = 0.0f;
1521  float minDistance = 8.0f;
1522  for (int i = -1; i <= 1; i++) {
1523  const float cellOffset = i;
1524  const float pointPosition = cellOffset +
1525  hash_float_to_float(cellPosition + cellOffset) * randomness;
1526  const float distanceToPoint = std::abs(pointPosition - localPosition);
1527  if (distanceToPoint < minDistance) {
1528  minDistance = distanceToPoint;
1529  closestPoint = pointPosition;
1530  closestPointOffset = cellOffset;
1531  }
1532  }
1533 
1534  minDistance = 8.0f;
1535  float closestPointToClosestPoint = 0.0f;
1536  for (int i = -1; i <= 1; i++) {
1537  if (i == 0) {
1538  continue;
1539  }
1540  const float cellOffset = i + closestPointOffset;
1541  const float pointPosition = cellOffset +
1542  hash_float_to_float(cellPosition + cellOffset) * randomness;
1543  const float distanceToPoint = std::abs(closestPoint - pointPosition);
1544  if (distanceToPoint < minDistance) {
1545  minDistance = distanceToPoint;
1546  closestPointToClosestPoint = pointPosition;
1547  }
1548  }
1549  *r_radius = std::abs(closestPointToClosestPoint - closestPoint) / 2.0f;
1550 }
1551 
1552 /* **** 2D Voronoi **** */
1553 
1554 static float voronoi_distance(const float2 a,
1555  const float2 b,
1556  const int metric,
1557  const float exponent)
1558 {
1559  switch (metric) {
1561  return math::distance(a, b);
1563  return std::abs(a.x - b.x) + std::abs(a.y - b.y);
1565  return std::max(std::abs(a.x - b.x), std::abs(a.y - b.y));
1567  return std::pow(std::pow(std::abs(a.x - b.x), exponent) +
1568  std::pow(std::abs(a.y - b.y), exponent),
1569  1.0f / exponent);
1570  default:
1572  break;
1573  }
1574  return 0.0f;
1575 }
1576 
1577 void voronoi_f1(const float2 coord,
1578  const float exponent,
1579  const float randomness,
1580  const int metric,
1581  float *r_distance,
1582  float3 *r_color,
1583  float2 *r_position)
1584 {
1585  const float2 cellPosition = math::floor(coord);
1586  const float2 localPosition = coord - cellPosition;
1587 
1588  float minDistance = 8.0f;
1589  float2 targetOffset = float2(0.0f, 0.0f);
1590  float2 targetPosition = float2(0.0f, 0.0f);
1591  for (int j = -1; j <= 1; j++) {
1592  for (int i = -1; i <= 1; i++) {
1593  const float2 cellOffset = float2(i, j);
1594  const float2 pointPosition = cellOffset +
1595  hash_float_to_float2(cellPosition + cellOffset) * randomness;
1596  float distanceToPoint = voronoi_distance(pointPosition, localPosition, metric, exponent);
1597  if (distanceToPoint < minDistance) {
1598  targetOffset = cellOffset;
1599  minDistance = distanceToPoint;
1600  targetPosition = pointPosition;
1601  }
1602  }
1603  }
1604  if (r_distance != nullptr) {
1605  *r_distance = minDistance;
1606  }
1607  if (r_color != nullptr) {
1608  *r_color = hash_float_to_float3(cellPosition + targetOffset);
1609  }
1610  if (r_position != nullptr) {
1611  *r_position = targetPosition + cellPosition;
1612  }
1613 }
1614 
1615 void voronoi_smooth_f1(const float2 coord,
1616  const float smoothness,
1617  const float exponent,
1618  const float randomness,
1619  const int metric,
1620  float *r_distance,
1621  float3 *r_color,
1622  float2 *r_position)
1623 {
1624  const float2 cellPosition = math::floor(coord);
1625  const float2 localPosition = coord - cellPosition;
1626  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
1627 
1628  float smoothDistance = 8.0f;
1629  float3 smoothColor = float3(0.0f, 0.0f, 0.0f);
1630  float2 smoothPosition = float2(0.0f, 0.0f);
1631  for (int j = -2; j <= 2; j++) {
1632  for (int i = -2; i <= 2; i++) {
1633  const float2 cellOffset = float2(i, j);
1634  const float2 pointPosition = cellOffset +
1635  hash_float_to_float2(cellPosition + cellOffset) * randomness;
1636  const float distanceToPoint = voronoi_distance(
1637  pointPosition, localPosition, metric, exponent);
1638  const float h = smoothstep(
1639  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness_clamped);
1640  float correctionFactor = smoothness * h * (1.0f - h);
1641  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
1642  if (r_color != nullptr || r_position != nullptr) {
1643  correctionFactor /= 1.0f + 3.0f * smoothness;
1644  if (r_color != nullptr) {
1645  const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
1646  smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
1647  }
1648  if (r_position != nullptr) {
1649  smoothPosition = math::interpolate(smoothPosition, pointPosition, h) - correctionFactor;
1650  }
1651  }
1652  }
1653  }
1654  if (r_distance != nullptr) {
1655  *r_distance = smoothDistance;
1656  }
1657  if (r_color != nullptr) {
1658  *r_color = smoothColor;
1659  }
1660  if (r_position != nullptr) {
1661  *r_position = cellPosition + smoothPosition;
1662  }
1663 }
1664 
1665 void voronoi_f2(const float2 coord,
1666  const float exponent,
1667  const float randomness,
1668  const int metric,
1669  float *r_distance,
1670  float3 *r_color,
1671  float2 *r_position)
1672 {
1673  const float2 cellPosition = math::floor(coord);
1674  const float2 localPosition = coord - cellPosition;
1675 
1676  float distanceF1 = 8.0f;
1677  float distanceF2 = 8.0f;
1678  float2 offsetF1 = float2(0.0f, 0.0f);
1679  float2 positionF1 = float2(0.0f, 0.0f);
1680  float2 offsetF2 = float2(0.0f, 0.0f);
1681  float2 positionF2 = float2(0.0f, 0.0f);
1682  for (int j = -1; j <= 1; j++) {
1683  for (int i = -1; i <= 1; i++) {
1684  const float2 cellOffset = float2(i, j);
1685  const float2 pointPosition = cellOffset +
1686  hash_float_to_float2(cellPosition + cellOffset) * randomness;
1687  const float distanceToPoint = voronoi_distance(
1688  pointPosition, localPosition, metric, exponent);
1689  if (distanceToPoint < distanceF1) {
1690  distanceF2 = distanceF1;
1691  distanceF1 = distanceToPoint;
1692  offsetF2 = offsetF1;
1693  offsetF1 = cellOffset;
1694  positionF2 = positionF1;
1695  positionF1 = pointPosition;
1696  }
1697  else if (distanceToPoint < distanceF2) {
1698  distanceF2 = distanceToPoint;
1699  offsetF2 = cellOffset;
1700  positionF2 = pointPosition;
1701  }
1702  }
1703  }
1704  if (r_distance != nullptr) {
1705  *r_distance = distanceF2;
1706  }
1707  if (r_color != nullptr) {
1708  *r_color = hash_float_to_float3(cellPosition + offsetF2);
1709  }
1710  if (r_position != nullptr) {
1711  *r_position = positionF2 + cellPosition;
1712  }
1713 }
1714 
1715 void voronoi_distance_to_edge(const float2 coord, const float randomness, float *r_distance)
1716 {
1717  const float2 cellPosition = math::floor(coord);
1718  const float2 localPosition = coord - cellPosition;
1719 
1720  float2 vectorToClosest = float2(0.0f, 0.0f);
1721  float minDistance = 8.0f;
1722  for (int j = -1; j <= 1; j++) {
1723  for (int i = -1; i <= 1; i++) {
1724  const float2 cellOffset = float2(i, j);
1725  const float2 vectorToPoint = cellOffset +
1726  hash_float_to_float2(cellPosition + cellOffset) * randomness -
1727  localPosition;
1728  const float distanceToPoint = math::dot(vectorToPoint, vectorToPoint);
1729  if (distanceToPoint < minDistance) {
1730  minDistance = distanceToPoint;
1731  vectorToClosest = vectorToPoint;
1732  }
1733  }
1734  }
1735 
1736  minDistance = 8.0f;
1737  for (int j = -1; j <= 1; j++) {
1738  for (int i = -1; i <= 1; i++) {
1739  const float2 cellOffset = float2(i, j);
1740  const float2 vectorToPoint = cellOffset +
1741  hash_float_to_float2(cellPosition + cellOffset) * randomness -
1742  localPosition;
1743  const float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
1744  if (math::dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
1745  const float distanceToEdge = math::dot((vectorToClosest + vectorToPoint) / 2.0f,
1746  math::normalize(perpendicularToEdge));
1747  minDistance = std::min(minDistance, distanceToEdge);
1748  }
1749  }
1750  }
1751  *r_distance = minDistance;
1752 }
1753 
1754 void voronoi_n_sphere_radius(const float2 coord, const float randomness, float *r_radius)
1755 {
1756  const float2 cellPosition = math::floor(coord);
1757  const float2 localPosition = coord - cellPosition;
1758 
1759  float2 closestPoint = float2(0.0f, 0.0f);
1760  float2 closestPointOffset = float2(0.0f, 0.0f);
1761  float minDistance = 8.0f;
1762  for (int j = -1; j <= 1; j++) {
1763  for (int i = -1; i <= 1; i++) {
1764  const float2 cellOffset = float2(i, j);
1765  const float2 pointPosition = cellOffset +
1766  hash_float_to_float2(cellPosition + cellOffset) * randomness;
1767  const float distanceToPoint = math::distance(pointPosition, localPosition);
1768  if (distanceToPoint < minDistance) {
1769  minDistance = distanceToPoint;
1770  closestPoint = pointPosition;
1771  closestPointOffset = cellOffset;
1772  }
1773  }
1774  }
1775 
1776  minDistance = 8.0f;
1777  float2 closestPointToClosestPoint = float2(0.0f, 0.0f);
1778  for (int j = -1; j <= 1; j++) {
1779  for (int i = -1; i <= 1; i++) {
1780  if (i == 0 && j == 0) {
1781  continue;
1782  }
1783  const float2 cellOffset = float2(i, j) + closestPointOffset;
1784  const float2 pointPosition = cellOffset +
1785  hash_float_to_float2(cellPosition + cellOffset) * randomness;
1786  const float distanceToPoint = math::distance(closestPoint, pointPosition);
1787  if (distanceToPoint < minDistance) {
1788  minDistance = distanceToPoint;
1789  closestPointToClosestPoint = pointPosition;
1790  }
1791  }
1792  }
1793  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
1794 }
1795 
1796 /* **** 3D Voronoi **** */
1797 
1798 static float voronoi_distance(const float3 a,
1799  const float3 b,
1800  const int metric,
1801  const float exponent)
1802 {
1803  switch (metric) {
1805  return math::distance(a, b);
1807  return std::abs(a.x - b.x) + std::abs(a.y - b.y) + std::abs(a.z - b.z);
1809  return std::max(std::abs(a.x - b.x), std::max(std::abs(a.y - b.y), std::abs(a.z - b.z)));
1811  return std::pow(std::pow(std::abs(a.x - b.x), exponent) +
1812  std::pow(std::abs(a.y - b.y), exponent) +
1813  std::pow(std::abs(a.z - b.z), exponent),
1814  1.0f / exponent);
1815  default:
1817  break;
1818  }
1819  return 0.0f;
1820 }
1821 
1822 void voronoi_f1(const float3 coord,
1823  const float exponent,
1824  const float randomness,
1825  const int metric,
1826  float *r_distance,
1827  float3 *r_color,
1828  float3 *r_position)
1829 {
1830  const float3 cellPosition = math::floor(coord);
1831  const float3 localPosition = coord - cellPosition;
1832 
1833  float minDistance = 8.0f;
1834  float3 targetOffset = float3(0.0f, 0.0f, 0.0f);
1835  float3 targetPosition = float3(0.0f, 0.0f, 0.0f);
1836  for (int k = -1; k <= 1; k++) {
1837  for (int j = -1; j <= 1; j++) {
1838  for (int i = -1; i <= 1; i++) {
1839  const float3 cellOffset = float3(i, j, k);
1840  const float3 pointPosition = cellOffset +
1841  hash_float_to_float3(cellPosition + cellOffset) * randomness;
1842  const float distanceToPoint = voronoi_distance(
1843  pointPosition, localPosition, metric, exponent);
1844  if (distanceToPoint < minDistance) {
1845  targetOffset = cellOffset;
1846  minDistance = distanceToPoint;
1847  targetPosition = pointPosition;
1848  }
1849  }
1850  }
1851  }
1852  if (r_distance != nullptr) {
1853  *r_distance = minDistance;
1854  }
1855  if (r_color != nullptr) {
1856  *r_color = hash_float_to_float3(cellPosition + targetOffset);
1857  }
1858  if (r_position != nullptr) {
1859  *r_position = targetPosition + cellPosition;
1860  }
1861 }
1862 
1863 void voronoi_smooth_f1(const float3 coord,
1864  const float smoothness,
1865  const float exponent,
1866  const float randomness,
1867  const int metric,
1868  float *r_distance,
1869  float3 *r_color,
1870  float3 *r_position)
1871 {
1872  const float3 cellPosition = math::floor(coord);
1873  const float3 localPosition = coord - cellPosition;
1874  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
1875 
1876  float smoothDistance = 8.0f;
1877  float3 smoothColor = float3(0.0f, 0.0f, 0.0f);
1878  float3 smoothPosition = float3(0.0f, 0.0f, 0.0f);
1879  for (int k = -2; k <= 2; k++) {
1880  for (int j = -2; j <= 2; j++) {
1881  for (int i = -2; i <= 2; i++) {
1882  const float3 cellOffset = float3(i, j, k);
1883  const float3 pointPosition = cellOffset +
1884  hash_float_to_float3(cellPosition + cellOffset) * randomness;
1885  const float distanceToPoint = voronoi_distance(
1886  pointPosition, localPosition, metric, exponent);
1887  const float h = smoothstep(
1888  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness_clamped);
1889  float correctionFactor = smoothness * h * (1.0f - h);
1890  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
1891  if (r_color != nullptr || r_position != nullptr) {
1892  correctionFactor /= 1.0f + 3.0f * smoothness;
1893  if (r_color != nullptr) {
1894  const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
1895  smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
1896  }
1897  if (r_position != nullptr) {
1898  smoothPosition = math::interpolate(smoothPosition, pointPosition, h) -
1899  correctionFactor;
1900  }
1901  }
1902  }
1903  }
1904  }
1905  if (r_distance != nullptr) {
1906  *r_distance = smoothDistance;
1907  }
1908  if (r_color != nullptr) {
1909  *r_color = smoothColor;
1910  }
1911  if (r_position != nullptr) {
1912  *r_position = cellPosition + smoothPosition;
1913  }
1914 }
1915 
1916 void voronoi_f2(const float3 coord,
1917  const float exponent,
1918  const float randomness,
1919  const int metric,
1920  float *r_distance,
1921  float3 *r_color,
1922  float3 *r_position)
1923 {
1924  const float3 cellPosition = math::floor(coord);
1925  const float3 localPosition = coord - cellPosition;
1926 
1927  float distanceF1 = 8.0f;
1928  float distanceF2 = 8.0f;
1929  float3 offsetF1 = float3(0.0f, 0.0f, 0.0f);
1930  float3 positionF1 = float3(0.0f, 0.0f, 0.0f);
1931  float3 offsetF2 = float3(0.0f, 0.0f, 0.0f);
1932  float3 positionF2 = float3(0.0f, 0.0f, 0.0f);
1933  for (int k = -1; k <= 1; k++) {
1934  for (int j = -1; j <= 1; j++) {
1935  for (int i = -1; i <= 1; i++) {
1936  const float3 cellOffset = float3(i, j, k);
1937  const float3 pointPosition = cellOffset +
1938  hash_float_to_float3(cellPosition + cellOffset) * randomness;
1939  const float distanceToPoint = voronoi_distance(
1940  pointPosition, localPosition, metric, exponent);
1941  if (distanceToPoint < distanceF1) {
1942  distanceF2 = distanceF1;
1943  distanceF1 = distanceToPoint;
1944  offsetF2 = offsetF1;
1945  offsetF1 = cellOffset;
1946  positionF2 = positionF1;
1947  positionF1 = pointPosition;
1948  }
1949  else if (distanceToPoint < distanceF2) {
1950  distanceF2 = distanceToPoint;
1951  offsetF2 = cellOffset;
1952  positionF2 = pointPosition;
1953  }
1954  }
1955  }
1956  }
1957  if (r_distance != nullptr) {
1958  *r_distance = distanceF2;
1959  }
1960  if (r_color != nullptr) {
1961  *r_color = hash_float_to_float3(cellPosition + offsetF2);
1962  }
1963  if (r_position != nullptr) {
1964  *r_position = positionF2 + cellPosition;
1965  }
1966 }
1967 
1968 void voronoi_distance_to_edge(const float3 coord, const float randomness, float *r_distance)
1969 {
1970  const float3 cellPosition = math::floor(coord);
1971  const float3 localPosition = coord - cellPosition;
1972 
1973  float3 vectorToClosest = float3(0.0f, 0.0f, 0.0f);
1974  float minDistance = 8.0f;
1975  for (int k = -1; k <= 1; k++) {
1976  for (int j = -1; j <= 1; j++) {
1977  for (int i = -1; i <= 1; i++) {
1978  const float3 cellOffset = float3(i, j, k);
1979  const float3 vectorToPoint = cellOffset +
1980  hash_float_to_float3(cellPosition + cellOffset) * randomness -
1981  localPosition;
1982  const float distanceToPoint = math::dot(vectorToPoint, vectorToPoint);
1983  if (distanceToPoint < minDistance) {
1984  minDistance = distanceToPoint;
1985  vectorToClosest = vectorToPoint;
1986  }
1987  }
1988  }
1989  }
1990 
1991  minDistance = 8.0f;
1992  for (int k = -1; k <= 1; k++) {
1993  for (int j = -1; j <= 1; j++) {
1994  for (int i = -1; i <= 1; i++) {
1995  const float3 cellOffset = float3(i, j, k);
1996  const float3 vectorToPoint = cellOffset +
1997  hash_float_to_float3(cellPosition + cellOffset) * randomness -
1998  localPosition;
1999  const float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
2000  if (math::dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
2001  const float distanceToEdge = math::dot((vectorToClosest + vectorToPoint) / 2.0f,
2002  math::normalize(perpendicularToEdge));
2003  minDistance = std::min(minDistance, distanceToEdge);
2004  }
2005  }
2006  }
2007  }
2008  *r_distance = minDistance;
2009 }
2010 
2011 void voronoi_n_sphere_radius(const float3 coord, const float randomness, float *r_radius)
2012 {
2013  const float3 cellPosition = math::floor(coord);
2014  const float3 localPosition = coord - cellPosition;
2015 
2016  float3 closestPoint = float3(0.0f, 0.0f, 0.0f);
2017  float3 closestPointOffset = float3(0.0f, 0.0f, 0.0f);
2018  float minDistance = 8.0f;
2019  for (int k = -1; k <= 1; k++) {
2020  for (int j = -1; j <= 1; j++) {
2021  for (int i = -1; i <= 1; i++) {
2022  const float3 cellOffset = float3(i, j, k);
2023  const float3 pointPosition = cellOffset +
2024  hash_float_to_float3(cellPosition + cellOffset) * randomness;
2025  const float distanceToPoint = math::distance(pointPosition, localPosition);
2026  if (distanceToPoint < minDistance) {
2027  minDistance = distanceToPoint;
2028  closestPoint = pointPosition;
2029  closestPointOffset = cellOffset;
2030  }
2031  }
2032  }
2033  }
2034 
2035  minDistance = 8.0f;
2036  float3 closestPointToClosestPoint = float3(0.0f, 0.0f, 0.0f);
2037  for (int k = -1; k <= 1; k++) {
2038  for (int j = -1; j <= 1; j++) {
2039  for (int i = -1; i <= 1; i++) {
2040  if (i == 0 && j == 0 && k == 0) {
2041  continue;
2042  }
2043  const float3 cellOffset = float3(i, j, k) + closestPointOffset;
2044  const float3 pointPosition = cellOffset +
2045  hash_float_to_float3(cellPosition + cellOffset) * randomness;
2046  const float distanceToPoint = math::distance(closestPoint, pointPosition);
2047  if (distanceToPoint < minDistance) {
2048  minDistance = distanceToPoint;
2049  closestPointToClosestPoint = pointPosition;
2050  }
2051  }
2052  }
2053  }
2054  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
2055 }
2056 
2057 /* **** 4D Voronoi **** */
2058 
2059 static float voronoi_distance(const float4 a,
2060  const float4 b,
2061  const int metric,
2062  const float exponent)
2063 {
2064  switch (metric) {
2066  return math::distance(a, b);
2068  return std::abs(a.x - b.x) + std::abs(a.y - b.y) + std::abs(a.z - b.z) + std::abs(a.w - b.w);
2070  return std::max(
2071  std::abs(a.x - b.x),
2072  std::max(std::abs(a.y - b.y), std::max(std::abs(a.z - b.z), std::abs(a.w - b.w))));
2074  return std::pow(
2075  std::pow(std::abs(a.x - b.x), exponent) + std::pow(std::abs(a.y - b.y), exponent) +
2076  std::pow(std::abs(a.z - b.z), exponent) + std::pow(std::abs(a.w - b.w), exponent),
2077  1.0f / exponent);
2078  default:
2080  break;
2081  }
2082  return 0.0f;
2083 }
2084 
2085 void voronoi_f1(const float4 coord,
2086  const float exponent,
2087  const float randomness,
2088  const int metric,
2089  float *r_distance,
2090  float3 *r_color,
2091  float4 *r_position)
2092 {
2093  const float4 cellPosition = math::floor(coord);
2094  const float4 localPosition = coord - cellPosition;
2095 
2096  float minDistance = 8.0f;
2097  float4 targetOffset = float4(0.0f, 0.0f, 0.0f, 0.0f);
2098  float4 targetPosition = float4(0.0f, 0.0f, 0.0f, 0.0f);
2099  for (int u = -1; u <= 1; u++) {
2100  for (int k = -1; k <= 1; k++) {
2101  for (int j = -1; j <= 1; j++) {
2102  for (int i = -1; i <= 1; i++) {
2103  const float4 cellOffset = float4(i, j, k, u);
2104  const float4 pointPosition = cellOffset +
2105  hash_float_to_float4(cellPosition + cellOffset) *
2106  randomness;
2107  const float distanceToPoint = voronoi_distance(
2108  pointPosition, localPosition, metric, exponent);
2109  if (distanceToPoint < minDistance) {
2110  targetOffset = cellOffset;
2111  minDistance = distanceToPoint;
2112  targetPosition = pointPosition;
2113  }
2114  }
2115  }
2116  }
2117  }
2118  if (r_distance != nullptr) {
2119  *r_distance = minDistance;
2120  }
2121  if (r_color != nullptr) {
2122  *r_color = hash_float_to_float3(cellPosition + targetOffset);
2123  }
2124  if (r_position != nullptr) {
2125  *r_position = targetPosition + cellPosition;
2126  }
2127 }
2128 
2129 void voronoi_smooth_f1(const float4 coord,
2130  const float smoothness,
2131  const float exponent,
2132  const float randomness,
2133  const int metric,
2134  float *r_distance,
2135  float3 *r_color,
2136  float4 *r_position)
2137 {
2138  const float4 cellPosition = math::floor(coord);
2139  const float4 localPosition = coord - cellPosition;
2140  const float smoothness_clamped = max_ff(smoothness, FLT_MIN);
2141 
2142  float smoothDistance = 8.0f;
2143  float3 smoothColor = float3(0.0f, 0.0f, 0.0f);
2144  float4 smoothPosition = float4(0.0f, 0.0f, 0.0f, 0.0f);
2145  for (int u = -2; u <= 2; u++) {
2146  for (int k = -2; k <= 2; k++) {
2147  for (int j = -2; j <= 2; j++) {
2148  for (int i = -2; i <= 2; i++) {
2149  const float4 cellOffset = float4(i, j, k, u);
2150  const float4 pointPosition = cellOffset +
2151  hash_float_to_float4(cellPosition + cellOffset) *
2152  randomness;
2153  const float distanceToPoint = voronoi_distance(
2154  pointPosition, localPosition, metric, exponent);
2155  const float h = smoothstep(
2156  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness_clamped);
2157  float correctionFactor = smoothness * h * (1.0f - h);
2158  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
2159  if (r_color != nullptr || r_position != nullptr) {
2160  correctionFactor /= 1.0f + 3.0f * smoothness;
2161  if (r_color != nullptr) {
2162  const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
2163  smoothColor = math::interpolate(smoothColor, cellColor, h) - correctionFactor;
2164  }
2165  if (r_position != nullptr) {
2166  smoothPosition = math::interpolate(smoothPosition, pointPosition, h) -
2167  correctionFactor;
2168  }
2169  }
2170  }
2171  }
2172  }
2173  }
2174  if (r_distance != nullptr) {
2175  *r_distance = smoothDistance;
2176  }
2177  if (r_color != nullptr) {
2178  *r_color = smoothColor;
2179  }
2180  if (r_position != nullptr) {
2181  *r_position = cellPosition + smoothPosition;
2182  }
2183 }
2184 
2185 void voronoi_f2(const float4 coord,
2186  const float exponent,
2187  const float randomness,
2188  const int metric,
2189  float *r_distance,
2190  float3 *r_color,
2191  float4 *r_position)
2192 {
2193  const float4 cellPosition = math::floor(coord);
2194  const float4 localPosition = coord - cellPosition;
2195 
2196  float distanceF1 = 8.0f;
2197  float distanceF2 = 8.0f;
2198  float4 offsetF1 = float4(0.0f, 0.0f, 0.0f, 0.0f);
2199  float4 positionF1 = float4(0.0f, 0.0f, 0.0f, 0.0f);
2200  float4 offsetF2 = float4(0.0f, 0.0f, 0.0f, 0.0f);
2201  float4 positionF2 = float4(0.0f, 0.0f, 0.0f, 0.0f);
2202  for (int u = -1; u <= 1; u++) {
2203  for (int k = -1; k <= 1; k++) {
2204  for (int j = -1; j <= 1; j++) {
2205  for (int i = -1; i <= 1; i++) {
2206  const float4 cellOffset = float4(i, j, k, u);
2207  const float4 pointPosition = cellOffset +
2208  hash_float_to_float4(cellPosition + cellOffset) *
2209  randomness;
2210  const float distanceToPoint = voronoi_distance(
2211  pointPosition, localPosition, metric, exponent);
2212  if (distanceToPoint < distanceF1) {
2213  distanceF2 = distanceF1;
2214  distanceF1 = distanceToPoint;
2215  offsetF2 = offsetF1;
2216  offsetF1 = cellOffset;
2217  positionF2 = positionF1;
2218  positionF1 = pointPosition;
2219  }
2220  else if (distanceToPoint < distanceF2) {
2221  distanceF2 = distanceToPoint;
2222  offsetF2 = cellOffset;
2223  positionF2 = pointPosition;
2224  }
2225  }
2226  }
2227  }
2228  }
2229  if (r_distance != nullptr) {
2230  *r_distance = distanceF2;
2231  }
2232  if (r_color != nullptr) {
2233  *r_color = hash_float_to_float3(cellPosition + offsetF2);
2234  }
2235  if (r_position != nullptr) {
2236  *r_position = positionF2 + cellPosition;
2237  }
2238 }
2239 
2240 void voronoi_distance_to_edge(const float4 coord, const float randomness, float *r_distance)
2241 {
2242  const float4 cellPosition = math::floor(coord);
2243  const float4 localPosition = coord - cellPosition;
2244 
2245  float4 vectorToClosest = float4(0.0f, 0.0f, 0.0f, 0.0f);
2246  float minDistance = 8.0f;
2247  for (int u = -1; u <= 1; u++) {
2248  for (int k = -1; k <= 1; k++) {
2249  for (int j = -1; j <= 1; j++) {
2250  for (int i = -1; i <= 1; i++) {
2251  const float4 cellOffset = float4(i, j, k, u);
2252  const float4 vectorToPoint = cellOffset +
2253  hash_float_to_float4(cellPosition + cellOffset) *
2254  randomness -
2255  localPosition;
2256  const float distanceToPoint = math::dot(vectorToPoint, vectorToPoint);
2257  if (distanceToPoint < minDistance) {
2258  minDistance = distanceToPoint;
2259  vectorToClosest = vectorToPoint;
2260  }
2261  }
2262  }
2263  }
2264  }
2265 
2266  minDistance = 8.0f;
2267  for (int u = -1; u <= 1; u++) {
2268  for (int k = -1; k <= 1; k++) {
2269  for (int j = -1; j <= 1; j++) {
2270  for (int i = -1; i <= 1; i++) {
2271  const float4 cellOffset = float4(i, j, k, u);
2272  const float4 vectorToPoint = cellOffset +
2273  hash_float_to_float4(cellPosition + cellOffset) *
2274  randomness -
2275  localPosition;
2276  const float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
2277  if (math::dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
2278  const float distanceToEdge = math::dot((vectorToClosest + vectorToPoint) / 2.0f,
2279  math::normalize(perpendicularToEdge));
2280  minDistance = std::min(minDistance, distanceToEdge);
2281  }
2282  }
2283  }
2284  }
2285  }
2286  *r_distance = minDistance;
2287 }
2288 
2289 void voronoi_n_sphere_radius(const float4 coord, const float randomness, float *r_radius)
2290 {
2291  const float4 cellPosition = math::floor(coord);
2292  const float4 localPosition = coord - cellPosition;
2293 
2294  float4 closestPoint = float4(0.0f, 0.0f, 0.0f, 0.0f);
2295  float4 closestPointOffset = float4(0.0f, 0.0f, 0.0f, 0.0f);
2296  float minDistance = 8.0f;
2297  for (int u = -1; u <= 1; u++) {
2298  for (int k = -1; k <= 1; k++) {
2299  for (int j = -1; j <= 1; j++) {
2300  for (int i = -1; i <= 1; i++) {
2301  const float4 cellOffset = float4(i, j, k, u);
2302  const float4 pointPosition = cellOffset +
2303  hash_float_to_float4(cellPosition + cellOffset) *
2304  randomness;
2305  const float distanceToPoint = math::distance(pointPosition, localPosition);
2306  if (distanceToPoint < minDistance) {
2307  minDistance = distanceToPoint;
2308  closestPoint = pointPosition;
2309  closestPointOffset = cellOffset;
2310  }
2311  }
2312  }
2313  }
2314  }
2315 
2316  minDistance = 8.0f;
2317  float4 closestPointToClosestPoint = float4(0.0f, 0.0f, 0.0f, 0.0f);
2318  for (int u = -1; u <= 1; u++) {
2319  for (int k = -1; k <= 1; k++) {
2320  for (int j = -1; j <= 1; j++) {
2321  for (int i = -1; i <= 1; i++) {
2322  if (i == 0 && j == 0 && k == 0 && u == 0) {
2323  continue;
2324  }
2325  const float4 cellOffset = float4(i, j, k, u) + closestPointOffset;
2326  const float4 pointPosition = cellOffset +
2327  hash_float_to_float4(cellPosition + cellOffset) *
2328  randomness;
2329  const float distanceToPoint = math::distance(closestPoint, pointPosition);
2330  if (distanceToPoint < minDistance) {
2331  minDistance = distanceToPoint;
2332  closestPointToClosestPoint = pointPosition;
2333  }
2334  }
2335  }
2336  }
2337  }
2338  *r_radius = math::distance(closestPointToClosestPoint, closestPoint) / 2.0f;
2339 }
2340 
2343 } // namespace blender::noise
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_INLINE
MINLINE float max_ff(float a, float b)
#define CLAMPIS(a, b, c)
#define ELEM(...)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble v1
#define X
Definition: GeomUtils.cpp:199
#define Z
Definition: GeomUtils.cpp:201
#define Y
Definition: GeomUtils.cpp:200
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
static T sum(const btAlignedObjectArray< T > &items)
static unsigned long seed
Definition: btSoftBody.h:39
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
MINLINE float smoothstep(float edge0, float edge1, float x)
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
#define T
#define H(x, y, z)
#define floorf(x)
Definition: metal/compat.h:224
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
T dot(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T distance(const T &a, const T &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
T floor(const T &a)
T abs(const T &a)
T interpolate(const T &a, const T &b, const FactorT &t)
void voronoi_n_sphere_radius(float w, float randomness, float *r_radius)
Definition: noise.cc:1514
void voronoi_smooth_f1(float w, float smoothness, float randomness, float *r_distance, float3 *r_color, float *r_w)
Definition: noise.cc:1411
float perlin_fractal_distorted(float position, float octaves, float roughness, float distortion)
Definition: noise.cc:643
BLI_INLINE float negate_if(float value, uint32_t condition)
Definition: noise.cc:343
float perlin_fractal(float position, float octaves, float roughness)
Definition: noise.cc:560
BLI_INLINE float uint_to_float_01(uint32_t k)
Definition: noise.cc:151
void voronoi_distance_to_edge(float w, float randomness, float *r_distance)
Definition: noise.cc:1498
BLI_INLINE float mix(float v0, float v1, float x)
Definition: noise.cc:252
uint32_t hash_float(float kx)
Definition: noise.cc:129
BLI_INLINE float perlin_distortion(float position, float strength)
Definition: noise.cc:615
float hash_float_to_float(float k)
Definition: noise.cc:178
float perlin_signed(float position)
Definition: noise.cc:489
BLI_INLINE void hash_bit_mix(uint32_t &a, uint32_t &b, uint32_t &c)
Definition: noise.cc:27
BLI_INLINE float voronoi_distance(const float a, const float b)
Definition: noise.cc:1375
BLI_INLINE float fade(float t)
Definition: noise.cc:338
float perlin(float position)
Definition: noise.cc:511
BLI_INLINE float random_float_offset(float seed)
Definition: noise.cc:587
BLI_INLINE float floor_fraction(float x, int &i)
Definition: noise.cc:381
BLI_INLINE uint32_t float_as_uint(float f)
Definition: noise.cc:119
BLI_INLINE float3 random_float3_offset(float seed)
Definition: noise.cc:598
float musgrave_multi_fractal(float co, float H, float lacunarity, float octaves)
Definition: noise.cc:747
float musgrave_ridged_multi_fractal(float co, float H, float lacunarity, float octaves, float offset, float gain)
Definition: noise.cc:843
BLI_INLINE float2 random_float2_offset(float seed)
Definition: noise.cc:592
float musgrave_fBm(float co, float H, float lacunarity, float octaves)
Definition: noise.cc:720
float musgrave_hybrid_multi_fractal(float co, float H, float lacunarity, float octaves, float offset, float gain)
Definition: noise.cc:803
float3 hash_float_to_float3(float k)
Definition: noise.cc:203
uint32_t hash(uint32_t kx)
Definition: noise.cc:67
BLI_INLINE float4 random_float4_offset(float seed)
Definition: noise.cc:605
BLI_INLINE float perlin_noise(float position)
Definition: noise.cc:387
float musgrave_hetero_terrain(float co, float H, float lacunarity, float octaves, float offset)
Definition: noise.cc:772
BLI_INLINE void hash_bit_final(uint32_t &a, uint32_t &b, uint32_t &c)
Definition: noise.cc:49
float4 hash_float_to_float4(float4 k)
Definition: noise.cc:231
float perlin_fractal_template(T position, float octaves, float roughness)
Definition: noise.cc:533
void voronoi_f1(float w, float randomness, float *r_distance, float3 *r_color, float *r_w)
Definition: noise.cc:1380
BLI_INLINE float noise_grad(uint32_t hash, float x)
Definition: noise.cc:348
float3 perlin_float3_fractal_distorted(float position, float octaves, float roughness, float distortion)
Definition: noise.cc:670
BLI_INLINE uint32_t hash_bit_rotate(uint32_t x, uint32_t k)
Definition: noise.cc:22
@ NOISE_SHD_VORONOI_MANHATTAN
Definition: noise.cc:1370
@ NOISE_SHD_VORONOI_MINKOWSKI
Definition: noise.cc:1372
@ NOISE_SHD_VORONOI_EUCLIDEAN
Definition: noise.cc:1369
@ NOISE_SHD_VORONOI_CHEBYCHEV
Definition: noise.cc:1371
float2 hash_float_to_float2(float2 k)
Definition: noise.cc:198
void voronoi_f2(float w, float randomness, float *r_distance, float3 *r_color, float *r_w)
Definition: noise.cc:1456
float hash_to_float(uint32_t kx)
Definition: noise.cc:156
vec_base< float, 3 > float3
vec_base< float, 4 > float4
vec_base< float, 2 > float2
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
static const pxr::TfToken roughness("roughness", pxr::TfToken::Immortal)
#define min(a, b)
Definition: sort.c:35
unsigned int uint32_t
Definition: stdint.h:80
float max