Blender V5.0
voronoi.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include "kernel/svm/util.h"
8#include "util/hash.h"
9
11
12/*
13 * SPDX-License-Identifier: MIT
14 * Original code is copyright (c) 2013 Inigo Quilez.
15 *
16 * Smooth Voronoi:
17 *
18 * - https://wiki.blender.org/wiki/User:OmarSquircleArt/GSoC2019/Documentation/Smooth_Voronoi
19 *
20 * Distance To Edge based on:
21 *
22 * - https://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm
23 * - https://www.shadertoy.com/view/ldl3W8
24 *
25 * With optimization to change -2..2 scan window to -1..1 for better performance,
26 * as explained in https://www.shadertoy.com/view/llG3zy.
27 */
28
29struct VoronoiParams {
30 float scale;
31 float detail;
32 float roughness;
33 float lacunarity;
34 float smoothness;
35 float exponent;
36 float randomness;
37 float max_distance;
41};
42
43struct VoronoiOutput {
44 float distance = 0.0f;
47};
48
49/* ***** Distances ***** */
50
51ccl_device float voronoi_distance(const float a, const float b)
52{
53 return fabsf(b - a);
54}
55
56template<typename T>
58{
59 if (params.metric == NODE_VORONOI_EUCLIDEAN) {
60 return distance(a, b);
61 }
62 if (params.metric == NODE_VORONOI_MANHATTAN) {
63 return reduce_add(fabs(a - b));
64 }
65 if (params.metric == NODE_VORONOI_CHEBYCHEV) {
66 return reduce_max(fabs(a - b));
67 }
68 if (params.metric == NODE_VORONOI_MINKOWSKI) {
69 return powf(reduce_add(power(fabs(a - b), params.exponent)), 1.0f / params.exponent);
70 }
71 return 0.0f;
72}
73
74/* Possibly cheaper/faster version of Voronoi distance, in a way that does not change
75 * logic of "which distance is the closest?". */
76template<typename T>
78 const T b,
80{
81 if (params.metric == NODE_VORONOI_EUCLIDEAN) {
82 return len_squared(a - b);
83 }
84 if (params.metric == NODE_VORONOI_MANHATTAN) {
85 return reduce_add(fabs(a - b));
86 }
87 if (params.metric == NODE_VORONOI_CHEBYCHEV) {
88 return reduce_max(fabs(a - b));
89 }
90 if (params.metric == NODE_VORONOI_MINKOWSKI) {
91 return reduce_add(power(fabs(a - b), params.exponent));
92 }
93 return 0.0f;
94}
95
96/* **** 1D Voronoi **** */
97
99{
100 return make_float4(0.0f, 0.0f, 0.0f, coord);
101}
102
104{
105 const float cellPosition = floorf(coord);
106 const float localPosition = coord - cellPosition;
107
108 float minDistance = FLT_MAX;
109 float targetOffset = 0.0f;
110 float targetPosition = 0.0f;
111 for (int i = -1; i <= 1; i++) {
112 const float cellOffset = i;
113 const float pointPosition = cellOffset +
114 hash_float_to_float(cellPosition + cellOffset) * params.randomness;
115 const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
116 if (distanceToPoint < minDistance) {
117 targetOffset = cellOffset;
118 minDistance = distanceToPoint;
119 targetPosition = pointPosition;
120 }
121 }
122
123 VoronoiOutput octave;
124 octave.distance = minDistance;
125 octave.color = hash_float_to_float3(cellPosition + targetOffset);
126 octave.position = voronoi_position(targetPosition + cellPosition);
127 return octave;
128}
129
131 const float coord)
132{
133 const float cellPosition = floorf(coord);
134 const float localPosition = coord - cellPosition;
135
136 float smoothDistance = 0.0f;
137 float smoothPosition = 0.0f;
138 float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
139 float h = -1.0f;
140 for (int i = -2; i <= 2; i++) {
141 const float cellOffset = i;
142 const float pointPosition = cellOffset +
143 hash_float_to_float(cellPosition + cellOffset) * params.randomness;
144 const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
145 h = h == -1.0f ?
146 1.0f :
148 0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / params.smoothness);
149 float correctionFactor = params.smoothness * h * (1.0f - h);
150 smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
151 correctionFactor /= 1.0f + 3.0f * params.smoothness;
152 const float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
153 smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
154 smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
155 }
156
157 VoronoiOutput octave;
158 octave.distance = smoothDistance;
159 octave.color = smoothColor;
160 octave.position = voronoi_position(cellPosition + smoothPosition);
161 return octave;
162}
163
165{
166 const float cellPosition = floorf(coord);
167 const float localPosition = coord - cellPosition;
168
169 float distanceF1 = FLT_MAX;
170 float distanceF2 = FLT_MAX;
171 float offsetF1 = 0.0f;
172 float positionF1 = 0.0f;
173 float offsetF2 = 0.0f;
174 float positionF2 = 0.0f;
175 for (int i = -1; i <= 1; i++) {
176 const float cellOffset = i;
177 const float pointPosition = cellOffset +
178 hash_float_to_float(cellPosition + cellOffset) * params.randomness;
179 const float distanceToPoint = voronoi_distance(pointPosition, localPosition);
180 if (distanceToPoint < distanceF1) {
181 distanceF2 = distanceF1;
182 distanceF1 = distanceToPoint;
183 offsetF2 = offsetF1;
184 offsetF1 = cellOffset;
185 positionF2 = positionF1;
186 positionF1 = pointPosition;
187 }
188 else if (distanceToPoint < distanceF2) {
189 distanceF2 = distanceToPoint;
190 offsetF2 = cellOffset;
191 positionF2 = pointPosition;
192 }
193 }
194
195 VoronoiOutput octave;
196 octave.distance = distanceF2;
197 octave.color = hash_float_to_float3(cellPosition + offsetF2);
198 octave.position = voronoi_position(positionF2 + cellPosition);
199 return octave;
200}
201
203 const float coord)
204{
205 const float cellPosition = floorf(coord);
206 const float localPosition = coord - cellPosition;
207
208 const float midPointPosition = hash_float_to_float(cellPosition) * params.randomness;
209 const float leftPointPosition = -1.0f +
210 hash_float_to_float(cellPosition - 1.0f) * params.randomness;
211 const float rightPointPosition = 1.0f +
212 hash_float_to_float(cellPosition + 1.0f) * params.randomness;
213 const float distanceToMidLeft = fabsf((midPointPosition + leftPointPosition) / 2.0f -
214 localPosition);
215 const float distanceToMidRight = fabsf((midPointPosition + rightPointPosition) / 2.0f -
216 localPosition);
217
218 return min(distanceToMidLeft, distanceToMidRight);
219}
220
222 const float coord)
223{
224 const float cellPosition = floorf(coord);
225 const float localPosition = coord - cellPosition;
226
227 float closestPoint = 0.0f;
228 float closestPointOffset = 0.0f;
229 float minDistance = FLT_MAX;
230 for (int i = -1; i <= 1; i++) {
231 const float cellOffset = i;
232 const float pointPosition = cellOffset +
233 hash_float_to_float(cellPosition + cellOffset) * params.randomness;
234 const float distanceToPoint = fabsf(pointPosition - localPosition);
235 if (distanceToPoint < minDistance) {
236 minDistance = distanceToPoint;
237 closestPoint = pointPosition;
238 closestPointOffset = cellOffset;
239 }
240 }
241
242 minDistance = FLT_MAX;
243 float closestPointToClosestPoint = 0.0f;
244 for (int i = -1; i <= 1; i++) {
245 if (i == 0) {
246 continue;
247 }
248 const float cellOffset = i + closestPointOffset;
249 const float pointPosition = cellOffset +
250 hash_float_to_float(cellPosition + cellOffset) * params.randomness;
251 const float distanceToPoint = fabsf(closestPoint - pointPosition);
252 if (distanceToPoint < minDistance) {
253 minDistance = distanceToPoint;
254 closestPointToClosestPoint = pointPosition;
255 }
256 }
257
258 return fabsf(closestPointToClosestPoint - closestPoint) / 2.0f;
259}
260
261/* **** 2D Voronoi **** */
262
264{
265 return make_float4(coord.x, coord.y, 0.0f, 0.0f);
266}
267
269{
270 const float2 cellPosition_f = floor(coord);
271 const float2 localPosition = coord - cellPosition_f;
272 const int2 cellPosition = make_int2(cellPosition_f);
273
274 float minDistance = FLT_MAX;
275 int2 targetOffset = make_int2(0);
276 float2 targetPosition = make_float2(0.0f, 0.0f);
277 for (int j = -1; j <= 1; j++) {
278 for (int i = -1; i <= 1; i++) {
279 const int2 cellOffset = make_int2(i, j);
280 const float2 pointPosition = make_float2(cellOffset) +
281 hash_int2_to_float2(cellPosition + cellOffset) *
282 params.randomness;
283 const float distanceToPoint = voronoi_distance_bound(pointPosition, localPosition, params);
284 if (distanceToPoint < minDistance) {
285 targetOffset = cellOffset;
286 minDistance = distanceToPoint;
287 targetPosition = pointPosition;
288 }
289 }
290 }
291
292 VoronoiOutput octave;
293 octave.distance = voronoi_distance(targetPosition, localPosition, params);
294 octave.color = hash_int2_to_float3(cellPosition + targetOffset);
295 octave.position = voronoi_position(targetPosition + cellPosition_f);
296 return octave;
297}
298
300 const float2 coord)
301{
302 const float2 cellPosition_f = floor(coord);
303 const float2 localPosition = coord - cellPosition_f;
304 const int2 cellPosition = make_int2(cellPosition_f);
305
306 float smoothDistance = 0.0f;
307 float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
308 float2 smoothPosition = make_float2(0.0f, 0.0f);
309 float h = -1.0f;
310 for (int j = -2; j <= 2; j++) {
311 for (int i = -2; i <= 2; i++) {
312 const int2 cellOffset = make_int2(i, j);
313 const float2 pointPosition = make_float2(cellOffset) +
314 hash_int2_to_float2(cellPosition + cellOffset) *
315 params.randomness;
316 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
317 h = h == -1.0f ?
318 1.0f :
319 smoothstep(0.0f,
320 1.0f,
321 0.5f + 0.5f * (smoothDistance - distanceToPoint) / params.smoothness);
322 float correctionFactor = params.smoothness * h * (1.0f - h);
323 smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
324 correctionFactor /= 1.0f + 3.0f * params.smoothness;
325 const float3 cellColor = hash_int2_to_float3(cellPosition + cellOffset);
326 smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
327 smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
328 }
329 }
330
331 VoronoiOutput octave;
332 octave.distance = smoothDistance;
333 octave.color = smoothColor;
334 octave.position = voronoi_position(cellPosition_f + smoothPosition);
335 return octave;
336}
337
339{
340 const float2 cellPosition_f = floor(coord);
341 const float2 localPosition = coord - cellPosition_f;
342 const int2 cellPosition = make_int2(cellPosition_f);
343
344 float distanceF1 = FLT_MAX;
345 float distanceF2 = FLT_MAX;
346 int2 offsetF1 = make_int2(0);
347 float2 positionF1 = make_float2(0.0f, 0.0f);
348 int2 offsetF2 = make_int2(0);
349 float2 positionF2 = make_float2(0.0f, 0.0f);
350 for (int j = -1; j <= 1; j++) {
351 for (int i = -1; i <= 1; i++) {
352 const int2 cellOffset = make_int2(i, j);
353 const float2 pointPosition = make_float2(cellOffset) +
354 hash_int2_to_float2(cellPosition + cellOffset) *
355 params.randomness;
356 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
357 if (distanceToPoint < distanceF1) {
358 distanceF2 = distanceF1;
359 distanceF1 = distanceToPoint;
360 offsetF2 = offsetF1;
361 offsetF1 = cellOffset;
362 positionF2 = positionF1;
363 positionF1 = pointPosition;
364 }
365 else if (distanceToPoint < distanceF2) {
366 distanceF2 = distanceToPoint;
367 offsetF2 = cellOffset;
368 positionF2 = pointPosition;
369 }
370 }
371 }
372
373 VoronoiOutput octave;
374 octave.distance = distanceF2;
375 octave.color = hash_int2_to_float3(cellPosition + offsetF2);
376 octave.position = voronoi_position(positionF2 + cellPosition_f);
377 return octave;
378}
379
381 const float2 coord)
382{
383 const float2 cellPosition_f = floor(coord);
384 const float2 localPosition = coord - cellPosition_f;
385 const int2 cellPosition = make_int2(cellPosition_f);
386
387 float2 vectorToClosest = make_float2(0.0f, 0.0f);
388 float minDistance = FLT_MAX;
389 for (int j = -1; j <= 1; j++) {
390 for (int i = -1; i <= 1; i++) {
391 const int2 cellOffset = make_int2(i, j);
392 const float2 vectorToPoint = make_float2(cellOffset) +
393 hash_int2_to_float2(cellPosition + cellOffset) *
394 params.randomness -
395 localPosition;
396 const float distanceToPoint = dot(vectorToPoint, vectorToPoint);
397 if (distanceToPoint < minDistance) {
398 minDistance = distanceToPoint;
399 vectorToClosest = vectorToPoint;
400 }
401 }
402 }
403
404 minDistance = FLT_MAX;
405 for (int j = -1; j <= 1; j++) {
406 for (int i = -1; i <= 1; i++) {
407 const int2 cellOffset = make_int2(i, j);
408 const float2 vectorToPoint = make_float2(cellOffset) +
409 hash_int2_to_float2(cellPosition + cellOffset) *
410 params.randomness -
411 localPosition;
412 const float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
413 if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
414 const float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
415 normalize(perpendicularToEdge));
416 minDistance = min(minDistance, distanceToEdge);
417 }
418 }
419 }
420
421 return minDistance;
422}
423
425 const float2 coord)
426{
427 const float2 cellPosition_f = floor(coord);
428 const float2 localPosition = coord - cellPosition_f;
429 const int2 cellPosition = make_int2(cellPosition_f);
430
431 float2 closestPoint = make_float2(0.0f, 0.0f);
432 int2 closestPointOffset = make_int2(0);
433 float minDistanceSq = FLT_MAX;
434 for (int j = -1; j <= 1; j++) {
435 for (int i = -1; i <= 1; i++) {
436 const int2 cellOffset = make_int2(i, j);
437 const float2 pointPosition = make_float2(cellOffset) +
438 hash_int2_to_float2(cellPosition + cellOffset) *
439 params.randomness;
440 const float distanceToPointSq = len_squared(pointPosition - localPosition);
441 if (distanceToPointSq < minDistanceSq) {
442 minDistanceSq = distanceToPointSq;
443 closestPoint = pointPosition;
444 closestPointOffset = cellOffset;
445 }
446 }
447 }
448
449 minDistanceSq = FLT_MAX;
450 float2 closestPointToClosestPoint = make_float2(0.0f, 0.0f);
451 for (int j = -1; j <= 1; j++) {
452 for (int i = -1; i <= 1; i++) {
453 if (i == 0 && j == 0) {
454 continue;
455 }
456 const int2 cellOffset = make_int2(i, j) + closestPointOffset;
457 const float2 pointPosition = make_float2(cellOffset) +
458 hash_int2_to_float2(cellPosition + cellOffset) *
459 params.randomness;
460 const float distanceToPointSq = len_squared(closestPoint - pointPosition);
461 if (distanceToPointSq < minDistanceSq) {
462 minDistanceSq = distanceToPointSq;
463 closestPointToClosestPoint = pointPosition;
464 }
465 }
466 }
467
468 return distance(closestPointToClosestPoint, closestPoint) / 2.0f;
469}
470
471/* **** 3D Voronoi **** */
472
474{
475 return make_float4(coord);
476}
477
479{
480 const float3 cellPosition_f = floor(coord);
481 const float3 localPosition = coord - cellPosition_f;
482 const int3 cellPosition = make_int3(cellPosition_f);
483
484 float minDistance = FLT_MAX;
485 int3 targetOffset = make_int3(0);
486 float3 targetPosition = make_float3(0.0f, 0.0f, 0.0f);
487 for (int k = -1; k <= 1; k++) {
488 for (int j = -1; j <= 1; j++) {
489 for (int i = -1; i <= 1; i++) {
490 const int3 cellOffset = make_int3(i, j, k);
491 const float3 pointPosition = make_float3(cellOffset) +
492 hash_int3_to_float3(cellPosition + cellOffset) *
493 params.randomness;
494 const float distanceToPoint = voronoi_distance_bound(pointPosition, localPosition, params);
495 if (distanceToPoint < minDistance) {
496 targetOffset = cellOffset;
497 minDistance = distanceToPoint;
498 targetPosition = pointPosition;
499 }
500 }
501 }
502 }
503
504 VoronoiOutput octave;
505 octave.distance = voronoi_distance(targetPosition, localPosition, params);
506 octave.color = hash_int3_to_float3(cellPosition + targetOffset);
507 octave.position = voronoi_position(targetPosition + cellPosition_f);
508 return octave;
509}
510
512 const float3 coord)
513{
514 const float3 cellPosition_f = floor(coord);
515 const float3 localPosition = coord - cellPosition_f;
516 const int3 cellPosition = make_int3(cellPosition_f);
517
518 float smoothDistance = 0.0f;
519 float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
520 float3 smoothPosition = make_float3(0.0f, 0.0f, 0.0f);
521 float h = -1.0f;
522 for (int k = -2; k <= 2; k++) {
523 for (int j = -2; j <= 2; j++) {
524 for (int i = -2; i <= 2; i++) {
525 const int3 cellOffset = make_int3(i, j, k);
526 const float3 pointPosition = make_float3(cellOffset) +
527 hash_int3_to_float3(cellPosition + cellOffset) *
528 params.randomness;
529 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
530 h = h == -1.0f ?
531 1.0f :
532 smoothstep(0.0f,
533 1.0f,
534 0.5f + 0.5f * (smoothDistance - distanceToPoint) / params.smoothness);
535 float correctionFactor = params.smoothness * h * (1.0f - h);
536 smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
537 correctionFactor /= 1.0f + 3.0f * params.smoothness;
538 const float3 cellColor = hash_int3_to_float3(cellPosition + cellOffset);
539 smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
540 smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
541 }
542 }
543 }
544
545 VoronoiOutput octave;
546 octave.distance = smoothDistance;
547 octave.color = smoothColor;
548 octave.position = voronoi_position(cellPosition_f + smoothPosition);
549 return octave;
550}
551
553{
554 const float3 cellPosition_f = floor(coord);
555 const float3 localPosition = coord - cellPosition_f;
556 const int3 cellPosition = make_int3(cellPosition_f);
557
558 float distanceF1 = FLT_MAX;
559 float distanceF2 = FLT_MAX;
560 int3 offsetF1 = make_int3(0);
561 float3 positionF1 = make_float3(0.0f, 0.0f, 0.0f);
562 int3 offsetF2 = make_int3(0);
563 float3 positionF2 = make_float3(0.0f, 0.0f, 0.0f);
564 for (int k = -1; k <= 1; k++) {
565 for (int j = -1; j <= 1; j++) {
566 for (int i = -1; i <= 1; i++) {
567 const int3 cellOffset = make_int3(i, j, k);
568 const float3 pointPosition = make_float3(cellOffset) +
569 hash_int3_to_float3(cellPosition + cellOffset) *
570 params.randomness;
571 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
572 if (distanceToPoint < distanceF1) {
573 distanceF2 = distanceF1;
574 distanceF1 = distanceToPoint;
575 offsetF2 = offsetF1;
576 offsetF1 = cellOffset;
577 positionF2 = positionF1;
578 positionF1 = pointPosition;
579 }
580 else if (distanceToPoint < distanceF2) {
581 distanceF2 = distanceToPoint;
582 offsetF2 = cellOffset;
583 positionF2 = pointPosition;
584 }
585 }
586 }
587 }
588
589 VoronoiOutput octave;
590 octave.distance = distanceF2;
591 octave.color = hash_int3_to_float3(cellPosition + offsetF2);
592 octave.position = voronoi_position(positionF2 + cellPosition_f);
593 return octave;
594}
595
597 const float3 coord)
598{
599 const float3 cellPosition_f = floor(coord);
600 const float3 localPosition = coord - cellPosition_f;
601 const int3 cellPosition = make_int3(cellPosition_f);
602
603 float3 vectorToClosest = make_float3(0.0f, 0.0f, 0.0f);
604 float minDistance = FLT_MAX;
605 for (int k = -1; k <= 1; k++) {
606 for (int j = -1; j <= 1; j++) {
607 for (int i = -1; i <= 1; i++) {
608 const int3 cellOffset = make_int3(i, j, k);
609 const float3 vectorToPoint = make_float3(cellOffset) +
610 hash_int3_to_float3(cellPosition + cellOffset) *
611 params.randomness -
612 localPosition;
613 const float distanceToPoint = dot(vectorToPoint, vectorToPoint);
614 if (distanceToPoint < minDistance) {
615 minDistance = distanceToPoint;
616 vectorToClosest = vectorToPoint;
617 }
618 }
619 }
620 }
621
622 minDistance = FLT_MAX;
623 for (int k = -1; k <= 1; k++) {
624 for (int j = -1; j <= 1; j++) {
625 for (int i = -1; i <= 1; i++) {
626 const int3 cellOffset = make_int3(i, j, k);
627 const float3 vectorToPoint = make_float3(cellOffset) +
628 hash_int3_to_float3(cellPosition + cellOffset) *
629 params.randomness -
630 localPosition;
631 const float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
632 if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
633 const float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
634 normalize(perpendicularToEdge));
635 minDistance = min(minDistance, distanceToEdge);
636 }
637 }
638 }
639 }
640
641 return minDistance;
642}
643
645 const float3 coord)
646{
647 const float3 cellPosition_f = floor(coord);
648 const float3 localPosition = coord - cellPosition_f;
649 const int3 cellPosition = make_int3(cellPosition_f);
650
651 float3 closestPoint = make_float3(0.0f, 0.0f, 0.0f);
652 int3 closestPointOffset = make_int3(0);
653 float minDistanceSq = FLT_MAX;
654 for (int k = -1; k <= 1; k++) {
655 for (int j = -1; j <= 1; j++) {
656 for (int i = -1; i <= 1; i++) {
657 const int3 cellOffset = make_int3(i, j, k);
658 const float3 pointPosition = make_float3(cellOffset) +
659 hash_int3_to_float3(cellPosition + cellOffset) *
660 params.randomness;
661 const float distanceToPointSq = len_squared(pointPosition - localPosition);
662 if (distanceToPointSq < minDistanceSq) {
663 minDistanceSq = distanceToPointSq;
664 closestPoint = pointPosition;
665 closestPointOffset = cellOffset;
666 }
667 }
668 }
669 }
670
671 minDistanceSq = FLT_MAX;
672 float3 closestPointToClosestPoint = make_float3(0.0f, 0.0f, 0.0f);
673 for (int k = -1; k <= 1; k++) {
674 for (int j = -1; j <= 1; j++) {
675 for (int i = -1; i <= 1; i++) {
676 if (i == 0 && j == 0 && k == 0) {
677 continue;
678 }
679 const int3 cellOffset = make_int3(i, j, k) + closestPointOffset;
680 const float3 pointPosition = make_float3(cellOffset) +
681 hash_int3_to_float3(cellPosition + cellOffset) *
682 params.randomness;
683 const float distanceToPointSq = len_squared(closestPoint - pointPosition);
684 if (distanceToPointSq < minDistanceSq) {
685 minDistanceSq = distanceToPointSq;
686 closestPointToClosestPoint = pointPosition;
687 }
688 }
689 }
690 }
691
692 return distance(closestPointToClosestPoint, closestPoint) / 2.0f;
693}
694
695/* **** 4D Voronoi **** */
696
698{
699 return coord;
700}
701
703{
704 const float4 cellPosition_f = floor(coord);
705 const float4 localPosition = coord - cellPosition_f;
706 const int4 cellPosition = make_int4(cellPosition_f);
707
708 float minDistance = FLT_MAX;
709 int4 targetOffset = zero_int4();
710 float4 targetPosition = zero_float4();
711 for (int u = -1; u <= 1; u++) {
712 for (int k = -1; k <= 1; k++) {
713 for (int j = -1; j <= 1; j++) {
714 for (int i = -1; i <= 1; i++) {
715 const int4 cellOffset = make_int4(i, j, k, u);
716 const float4 pointPosition = make_float4(cellOffset) +
717 hash_int4_to_float4(cellPosition + cellOffset) *
718 params.randomness;
719 const float distanceToPoint = voronoi_distance_bound(
720 pointPosition, localPosition, params);
721 if (distanceToPoint < minDistance) {
722 targetOffset = cellOffset;
723 minDistance = distanceToPoint;
724 targetPosition = pointPosition;
725 }
726 }
727 }
728 }
729 }
730
731 VoronoiOutput octave;
732 octave.distance = voronoi_distance(targetPosition, localPosition, params);
733 octave.color = hash_int4_to_float3(cellPosition + targetOffset);
734 octave.position = voronoi_position(targetPosition + cellPosition_f);
735 return octave;
736}
737
739 const float4 coord)
740{
741 const float4 cellPosition_f = floor(coord);
742 const float4 localPosition = coord - cellPosition_f;
743 const int4 cellPosition = make_int4(cellPosition_f);
744
745 float smoothDistance = 0.0f;
746 float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
747 float4 smoothPosition = zero_float4();
748 float h = -1.0f;
749 for (int u = -2; u <= 2; u++) {
750 for (int k = -2; k <= 2; k++) {
751 for (int j = -2; j <= 2; j++) {
752 for (int i = -2; i <= 2; i++) {
753 const int4 cellOffset = make_int4(i, j, k, u);
754 const float4 pointPosition = make_float4(cellOffset) +
755 hash_int4_to_float4(cellPosition + cellOffset) *
756 params.randomness;
757 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
758 h = h == -1.0f ?
759 1.0f :
760 smoothstep(0.0f,
761 1.0f,
762 0.5f + 0.5f * (smoothDistance - distanceToPoint) / params.smoothness);
763 float correctionFactor = params.smoothness * h * (1.0f - h);
764 smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
765 correctionFactor /= 1.0f + 3.0f * params.smoothness;
766 const float3 cellColor = hash_int4_to_float3(cellPosition + cellOffset);
767 smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
768 smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
769 }
770 }
771 }
772 }
773
774 VoronoiOutput octave;
775 octave.distance = smoothDistance;
776 octave.color = smoothColor;
777 octave.position = voronoi_position(cellPosition_f + smoothPosition);
778 return octave;
779}
780
782{
783 const float4 cellPosition_f = floor(coord);
784 const float4 localPosition = coord - cellPosition_f;
785 const int4 cellPosition = make_int4(cellPosition_f);
786
787 float distanceF1 = FLT_MAX;
788 float distanceF2 = FLT_MAX;
789 int4 offsetF1 = zero_int4();
790 float4 positionF1 = zero_float4();
791 int4 offsetF2 = zero_int4();
792 float4 positionF2 = zero_float4();
793 for (int u = -1; u <= 1; u++) {
794 for (int k = -1; k <= 1; k++) {
795 for (int j = -1; j <= 1; j++) {
796 for (int i = -1; i <= 1; i++) {
797 const int4 cellOffset = make_int4(i, j, k, u);
798 const float4 pointPosition = make_float4(cellOffset) +
799 hash_int4_to_float4(cellPosition + cellOffset) *
800 params.randomness;
801 const float distanceToPoint = voronoi_distance(pointPosition, localPosition, params);
802 if (distanceToPoint < distanceF1) {
803 distanceF2 = distanceF1;
804 distanceF1 = distanceToPoint;
805 offsetF2 = offsetF1;
806 offsetF1 = cellOffset;
807 positionF2 = positionF1;
808 positionF1 = pointPosition;
809 }
810 else if (distanceToPoint < distanceF2) {
811 distanceF2 = distanceToPoint;
812 offsetF2 = cellOffset;
813 positionF2 = pointPosition;
814 }
815 }
816 }
817 }
818 }
819
820 VoronoiOutput octave;
821 octave.distance = distanceF2;
822 octave.color = hash_int4_to_float3(cellPosition + offsetF2);
823 octave.position = voronoi_position(positionF2 + cellPosition_f);
824 return octave;
825}
826
828 const float4 coord)
829{
830 const float4 cellPosition_f = floor(coord);
831 const float4 localPosition = coord - cellPosition_f;
832 const int4 cellPosition = make_int4(cellPosition_f);
833
834 float4 vectorToClosest = zero_float4();
835 float minDistance = FLT_MAX;
836 for (int u = -1; u <= 1; u++) {
837 for (int k = -1; k <= 1; k++) {
838 for (int j = -1; j <= 1; j++) {
839 for (int i = -1; i <= 1; i++) {
840 const int4 cellOffset = make_int4(i, j, k, u);
841 const float4 vectorToPoint = make_float4(cellOffset) +
842 hash_int4_to_float4(cellPosition + cellOffset) *
843 params.randomness -
844 localPosition;
845 const float distanceToPoint = dot(vectorToPoint, vectorToPoint);
846 if (distanceToPoint < minDistance) {
847 minDistance = distanceToPoint;
848 vectorToClosest = vectorToPoint;
849 }
850 }
851 }
852 }
853 }
854
855 minDistance = FLT_MAX;
856 for (int u = -1; u <= 1; u++) {
857 for (int k = -1; k <= 1; k++) {
858 for (int j = -1; j <= 1; j++) {
859 for (int i = -1; i <= 1; i++) {
860 const int4 cellOffset = make_int4(i, j, k, u);
861 const float4 vectorToPoint = make_float4(cellOffset) +
862 hash_int4_to_float4(cellPosition + cellOffset) *
863 params.randomness -
864 localPosition;
865 const float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
866 if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
867 const float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
868 normalize(perpendicularToEdge));
869 minDistance = min(minDistance, distanceToEdge);
870 }
871 }
872 }
873 }
874 }
875
876 return minDistance;
877}
878
880 const float4 coord)
881{
882 const float4 cellPosition_f = floor(coord);
883 const float4 localPosition = coord - cellPosition_f;
884 const int4 cellPosition = make_int4(cellPosition_f);
885
886 float4 closestPoint = zero_float4();
887 int4 closestPointOffset = zero_int4();
888 float minDistanceSq = FLT_MAX;
889 for (int u = -1; u <= 1; u++) {
890 for (int k = -1; k <= 1; k++) {
891 for (int j = -1; j <= 1; j++) {
892 for (int i = -1; i <= 1; i++) {
893 const int4 cellOffset = make_int4(i, j, k, u);
894 const float4 pointPosition = make_float4(cellOffset) +
895 hash_int4_to_float4(cellPosition + cellOffset) *
896 params.randomness;
897 const float distanceToPointSq = len_squared(pointPosition - localPosition);
898 if (distanceToPointSq < minDistanceSq) {
899 minDistanceSq = distanceToPointSq;
900 closestPoint = pointPosition;
901 closestPointOffset = cellOffset;
902 }
903 }
904 }
905 }
906 }
907
908 minDistanceSq = FLT_MAX;
909 float4 closestPointToClosestPoint = zero_float4();
910 for (int u = -1; u <= 1; u++) {
911 for (int k = -1; k <= 1; k++) {
912 for (int j = -1; j <= 1; j++) {
913 for (int i = -1; i <= 1; i++) {
914 if (i == 0 && j == 0 && k == 0 && u == 0) {
915 continue;
916 }
917 const int4 cellOffset = make_int4(i, j, k, u) + closestPointOffset;
918 const float4 pointPosition = make_float4(cellOffset) +
919 hash_int4_to_float4(cellPosition + cellOffset) *
920 params.randomness;
921 const float distanceToPointSq = len_squared(closestPoint - pointPosition);
922 if (distanceToPointSq < minDistanceSq) {
923 minDistanceSq = distanceToPointSq;
924 closestPointToClosestPoint = pointPosition;
925 }
926 }
927 }
928 }
929 }
930
931 return distance(closestPointToClosestPoint, closestPoint) / 2.0f;
932}
933
934/* **** Fractal Voronoi **** */
935
936/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
937 * by lerps. */
938template<typename T>
940 const T coord)
941{
942 float amplitude = 1.0f;
943 float max_amplitude = 0.0f;
944 float scale = 1.0f;
945
947 const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
948
949 for (int i = 0; i <= ceilf(params.detail); ++i) {
950 VoronoiOutput octave = (params.feature == NODE_VORONOI_F2) ?
951 voronoi_f2(params, coord * scale) :
952 (params.feature == NODE_VORONOI_SMOOTH_F1 &&
953 params.smoothness != 0.0f) ?
954 voronoi_smooth_f1(params, coord * scale) :
955 voronoi_f1(params, coord * scale);
956
957 if (zero_input) {
958 max_amplitude = 1.0f;
959 output = octave;
960 break;
961 }
962 if (i <= params.detail) {
963 max_amplitude += amplitude;
964 output.distance += octave.distance * amplitude;
965 output.color += octave.color * amplitude;
966 output.position = mix(output.position, octave.position / scale, amplitude);
967 scale *= params.lacunarity;
968 amplitude *= params.roughness;
969 }
970 else {
971 const float remainder = params.detail - floorf(params.detail);
972 if (remainder != 0.0f) {
973 max_amplitude = mix(max_amplitude, max_amplitude + amplitude, remainder);
974 output.distance = mix(
975 output.distance, output.distance + octave.distance * amplitude, remainder);
976 output.color = mix(output.color, output.color + octave.color * amplitude, remainder);
977 output.position = mix(
978 output.position, mix(output.position, octave.position / scale, amplitude), remainder);
979 }
980 }
981 }
982
983 if (params.normalize) {
984 output.distance /= max_amplitude * params.max_distance;
985 output.color /= max_amplitude;
986 }
987
988 output.position = safe_divide(output.position, params.scale);
989
990 return output;
991}
992
993/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
994 * by lerps. */
995template<typename T>
997 const T coord)
998{
999 float amplitude = 1.0f;
1000 float max_amplitude = params.max_distance;
1001 float scale = 1.0f;
1002 float distance = 8.0f;
1003
1004 const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
1005
1006 for (int i = 0; i <= ceilf(params.detail); ++i) {
1007 const float octave_distance = voronoi_distance_to_edge(params, coord * scale);
1008
1009 if (zero_input) {
1010 distance = octave_distance;
1011 break;
1012 }
1013 if (i <= params.detail) {
1014 max_amplitude = mix(max_amplitude, params.max_distance / scale, amplitude);
1015 distance = mix(distance, min(distance, octave_distance / scale), amplitude);
1016 scale *= params.lacunarity;
1017 amplitude *= params.roughness;
1018 }
1019 else {
1020 const float remainder = params.detail - floorf(params.detail);
1021 if (remainder != 0.0f) {
1022 const float lerp_amplitude = mix(max_amplitude, params.max_distance / scale, amplitude);
1023 max_amplitude = mix(max_amplitude, lerp_amplitude, remainder);
1024 const float lerp_distance = mix(
1025 distance, min(distance, octave_distance / scale), amplitude);
1026 distance = mix(distance, min(distance, lerp_distance), remainder);
1027 }
1028 }
1029 }
1030
1031 if (params.normalize) {
1032 distance /= max_amplitude;
1033 }
1034
1035 return distance;
1036}
1037
1038ccl_device void svm_voronoi_output(const uint4 stack_offsets,
1039 ccl_private float *stack,
1040 const float distance,
1041 const float3 color,
1042 const float3 position,
1043 const float w,
1044 const float radius)
1045{
1046 uint distance_stack_offset;
1047 uint color_stack_offset;
1048 uint position_stack_offset;
1049 uint w_out_stack_offset;
1050 uint radius_stack_offset;
1051 uint unused;
1052
1054 stack_offsets.z, &unused, &unused, &distance_stack_offset, &color_stack_offset);
1056 stack_offsets.w, &position_stack_offset, &w_out_stack_offset, &radius_stack_offset);
1057
1058 if (stack_valid(distance_stack_offset)) {
1059 stack_store_float(stack, distance_stack_offset, distance);
1060 }
1061 if (stack_valid(color_stack_offset)) {
1062 stack_store_float3(stack, color_stack_offset, color);
1063 }
1064 if (stack_valid(position_stack_offset)) {
1065 stack_store_float3(stack, position_stack_offset, position);
1066 }
1067 if (stack_valid(w_out_stack_offset)) {
1068 stack_store_float(stack, w_out_stack_offset, w);
1069 }
1070 if (stack_valid(radius_stack_offset)) {
1071 stack_store_float(stack, radius_stack_offset, radius);
1072 }
1073}
1074
1075template<uint node_feature_mask>
1077 ccl_private float *stack,
1078 const uint dimensions,
1079 const uint feature,
1080 const uint metric,
1081 int offset)
1082{
1083 /* Read node defaults and stack offsets. */
1084 const uint4 stack_offsets = read_node(kg, &offset);
1085 const uint4 defaults1 = read_node(kg, &offset);
1086 const uint4 defaults2 = read_node(kg, &offset);
1087
1088 uint coord_stack_offset;
1089 uint w_stack_offset;
1090 uint scale_stack_offset;
1091 uint detail_stack_offset;
1092 uint roughness_stack_offset;
1093 uint lacunarity_stack_offset;
1094 uint smoothness_stack_offset;
1095 uint exponent_stack_offset;
1096 uint randomness_stack_offset;
1098
1099 svm_unpack_node_uchar4(stack_offsets.x,
1100 &coord_stack_offset,
1101 &w_stack_offset,
1102 &scale_stack_offset,
1103 &detail_stack_offset);
1104 svm_unpack_node_uchar4(stack_offsets.y,
1105 &roughness_stack_offset,
1106 &lacunarity_stack_offset,
1107 &smoothness_stack_offset,
1108 &exponent_stack_offset);
1109 svm_unpack_node_uchar2(stack_offsets.z, &randomness_stack_offset, &normalize);
1110
1111 /* Read from stack. */
1112 float3 coord = stack_load_float3(stack, coord_stack_offset);
1113 float w = stack_load_float_default(stack, w_stack_offset, defaults1.x);
1114
1116 params.feature = (NodeVoronoiFeature)feature;
1117 params.metric = (NodeVoronoiDistanceMetric)metric;
1118 params.scale = stack_load_float_default(stack, scale_stack_offset, defaults1.y);
1119 params.detail = stack_load_float_default(stack, detail_stack_offset, defaults1.z);
1120 params.roughness = stack_load_float_default(stack, roughness_stack_offset, defaults1.w);
1121 params.lacunarity = stack_load_float_default(stack, lacunarity_stack_offset, defaults2.x);
1122 params.smoothness = stack_load_float_default(stack, smoothness_stack_offset, defaults2.y);
1123 params.exponent = stack_load_float_default(stack, exponent_stack_offset, defaults2.z);
1124 params.randomness = stack_load_float_default(stack, randomness_stack_offset, defaults2.w);
1125 params.max_distance = 0.0f;
1126 params.normalize = normalize;
1127
1128 params.detail = clamp(params.detail, 0.0f, 15.0f);
1129 params.roughness = clamp(params.roughness, 0.0f, 1.0f);
1130 params.randomness = clamp(params.randomness, 0.0f, 1.0f);
1131 params.smoothness = clamp(params.smoothness / 2.0f, 0.0f, 0.5f);
1132
1133 coord *= params.scale;
1134 w *= params.scale;
1135
1136 /* Compute output, specialized for each dimension. */
1137 switch (params.feature) {
1139 float distance = 0.0f;
1140 params.max_distance = 0.5f + 0.5f * params.randomness;
1141 switch (dimensions) {
1142 case 1:
1144 break;
1145 case 2:
1147 break;
1148 case 3:
1150 break;
1151 case 4:
1153 break;
1154 default:
1155 kernel_assert(0);
1156 break;
1157 }
1158
1159 svm_voronoi_output(stack_offsets, stack, distance, zero_float3(), zero_float3(), 0.0f, 0.0f);
1160 break;
1161 }
1163 float radius = 0.0f;
1164 switch (dimensions) {
1165 case 1:
1166 radius = voronoi_n_sphere_radius(params, w);
1167 break;
1168 case 2:
1169 radius = voronoi_n_sphere_radius(params, make_float2(coord));
1170 break;
1171 case 3:
1172 radius = voronoi_n_sphere_radius(params, coord);
1173 break;
1174 case 4:
1175 radius = voronoi_n_sphere_radius(params, make_float4(coord, w));
1176 break;
1177 default:
1178 kernel_assert(0);
1179 break;
1180 }
1181
1182 svm_voronoi_output(stack_offsets, stack, 0.0f, zero_float3(), zero_float3(), 0.0f, radius);
1183 break;
1184 }
1185 default: {
1187 switch (dimensions) {
1188 case 1:
1189 params.max_distance = (0.5f + 0.5f * params.randomness) *
1190 ((params.feature == NODE_VORONOI_F2) ? 2.0f : 1.0f);
1192 break;
1193 case 2:
1194 IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
1195 {
1196 params.max_distance = voronoi_distance(zero_float2(),
1197 make_float2(0.5f + 0.5f * params.randomness,
1198 0.5f + 0.5f * params.randomness),
1199 params) *
1200 ((params.feature == NODE_VORONOI_F2) ? 2.0f : 1.0f);
1202 }
1203 break;
1204 case 3:
1205 IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
1206 {
1207 params.max_distance = voronoi_distance(zero_float3(),
1208 make_float3(0.5f + 0.5f * params.randomness,
1209 0.5f + 0.5f * params.randomness,
1210 0.5f + 0.5f * params.randomness),
1211 params) *
1212 ((params.feature == NODE_VORONOI_F2) ? 2.0f : 1.0f);
1214 }
1215 break;
1216 case 4:
1217 IF_KERNEL_NODES_FEATURE(VORONOI_EXTRA)
1218 {
1219 params.max_distance = voronoi_distance(zero_float4(),
1220 make_float4(0.5f + 0.5f * params.randomness,
1221 0.5f + 0.5f * params.randomness,
1222 0.5f + 0.5f * params.randomness,
1223 0.5f + 0.5f * params.randomness),
1224 params) *
1225 ((params.feature == NODE_VORONOI_F2) ? 2.0f : 1.0f);
1227 }
1228 break;
1229 default:
1230 kernel_assert(0);
1231 break;
1232 }
1233
1234 svm_voronoi_output(stack_offsets,
1235 stack,
1236 output.distance,
1237 output.color,
1238 make_float3(output.position),
1239 output.position.w,
1240 0.0f);
1241 break;
1242 }
1243 }
1244
1245 return offset;
1246}
1247
MINLINE float safe_divide(float a, float b)
unsigned int uint
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
reduce_max(value.rgb)") DEFINE_VALUE("REDUCE(lhs
dot(value.rgb, luminance_coefficients)") DEFINE_VALUE("REDUCE(lhs
ccl_device_inline void stack_store_float(ccl_private float *stack, const uint a, const float f)
ccl_device_inline uint4 read_node(KernelGlobals kg, ccl_private int *const offset)
ccl_device_inline void stack_store_float3(ccl_private float *stack, const uint a, const float3 f)
ccl_device_inline float stack_load_float_default(const ccl_private float *stack, const uint a, const uint value)
ccl_device_forceinline void svm_unpack_node_uchar2(const uint i, ccl_private uint *x, ccl_private uint *y)
ccl_device_forceinline void svm_unpack_node_uchar3(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z)
ccl_device_forceinline void svm_unpack_node_uchar4(const uint i, ccl_private uint *x, ccl_private uint *y, ccl_private uint *z, ccl_private uint *w)
ccl_device_inline bool stack_valid(const uint a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(const ccl_private float *stack, const uint a)
#define kernel_assert(cond)
#define IF_KERNEL_NODES_FEATURE(feature)
#define ccl_private
const ThreadKernelGlobalsCPU * KernelGlobals
#define ccl_device_noinline
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline int3 make_int3(const int x, const int y, const int z)
ccl_device_forceinline int2 make_int2(const int x, const int y)
ccl_device_forceinline int4 make_int4(const int x, const int y, const int z, const int w)
#define output
VecBase< float, D > normalize(VecOp< float, D >) RET
#define floor
constexpr T clamp(T, U, U) RET
float distance(VecOp< float, D >, VecOp< float, D >) RET
ccl_device_inline float3 hash_float_to_float3(const float k)
Definition hash.h:300
ccl_device_inline float3 hash_int3_to_float3(const int3 k)
Definition hash.h:248
ccl_device_inline float3 hash_int4_to_float3(const int4 k)
Definition hash.h:267
ccl_device_inline float2 hash_int2_to_float2(const int2 k)
Definition hash.h:241
ccl_device_inline float3 hash_int2_to_float3(const int2 k)
Definition hash.h:262
ccl_device_inline float4 hash_int4_to_float4(const int4 k)
Definition hash.h:255
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
NodeVoronoiFeature
@ NODE_VORONOI_SMOOTH_F1
@ NODE_VORONOI_N_SPHERE_RADIUS
@ NODE_VORONOI_F2
@ NODE_VORONOI_DISTANCE_TO_EDGE
NodeVoronoiDistanceMetric
@ NODE_VORONOI_EUCLIDEAN
@ NODE_VORONOI_MANHATTAN
@ NODE_VORONOI_CHEBYCHEV
@ NODE_VORONOI_MINKOWSKI
MINLINE float smoothstep(float edge0, float edge1, float x)
ccl_device_inline dual1 reduce_add(const dual< T > a)
Definition math_dual.h:49
ccl_device_inline float2 power(const float2 v, const float e)
CCL_NAMESPACE_BEGIN ccl_device_inline float2 zero_float2()
Definition math_float2.h:13
ccl_device_inline float len_squared(const float2 a)
ccl_device_inline float2 fabs(const float2 a)
CCL_NAMESPACE_BEGIN ccl_device_inline float3 zero_float3()
Definition math_float3.h:17
CCL_NAMESPACE_BEGIN ccl_device_inline float4 zero_float4()
Definition math_float4.h:13
#define T
float hash_float_to_float(float k)
Definition node_hash.h:70
#define mix
#define floorf
#define fabsf
#define ccl_device
#define make_float2
#define make_float4
#define ceilf
#define min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
float3 color
Definition voronoi.h:45
float4 position
Definition voronoi.h:46
float distance
Definition voronoi.h:44
float x
float y
uint x
Definition types_uint4.h:13
uint y
Definition types_uint4.h:13
uint z
Definition types_uint4.h:13
uint w
Definition types_uint4.h:13
i
Definition text_draw.cc:230
ccl_device_inline int4 zero_int4()
Definition types_int4.h:79
ccl_device VoronoiOutput voronoi_f1(const ccl_private VoronoiParams &params, const float coord)
Definition voronoi.h:103
ccl_device float voronoi_distance_bound(const T a, const T b, const ccl_private VoronoiParams &params)
Definition voronoi.h:77
ccl_device float voronoi_distance(const float a, const float b)
Definition voronoi.h:51
ccl_device VoronoiOutput voronoi_smooth_f1(const ccl_private VoronoiParams &params, const float coord)
Definition voronoi.h:130
ccl_device float voronoi_n_sphere_radius(const ccl_private VoronoiParams &params, const float coord)
Definition voronoi.h:221
ccl_device VoronoiOutput fractal_voronoi_x_fx(const ccl_private VoronoiParams &params, const T coord)
Definition voronoi.h:939
ccl_device float4 voronoi_position(const float coord)
Definition voronoi.h:98
ccl_device void svm_voronoi_output(const uint4 stack_offsets, ccl_private float *stack, const float distance, const float3 color, const float3 position, const float w, const float radius)
Definition voronoi.h:1038
ccl_device float fractal_voronoi_distance_to_edge(const ccl_private VoronoiParams &params, const T coord)
Definition voronoi.h:996
ccl_device_noinline int svm_node_tex_voronoi(KernelGlobals kg, ccl_private float *stack, const uint dimensions, const uint feature, const uint metric, int offset)
Definition voronoi.h:1076
ccl_device float voronoi_distance_to_edge(const ccl_private VoronoiParams &params, const float coord)
Definition voronoi.h:202
ccl_device VoronoiOutput voronoi_f2(const ccl_private VoronoiParams &params, const float coord)
Definition voronoi.h:164