Blender  V2.93
svm_voronoi.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 /*
20  * Smooth Voronoi:
21  *
22  * - https://wiki.blender.org/wiki/User:OmarSquircleArt/GSoC2019/Documentation/Smooth_Voronoi
23  *
24  * Distance To Edge:
25  *
26  * - https://www.shadertoy.com/view/llG3zy
27  *
28  */
29 
30 /* **** 1D Voronoi **** */
31 
33  float b,
35  float exponent)
36 {
37  return fabsf(b - a);
38 }
39 
41  float exponent,
42  float randomness,
44  float *outDistance,
45  float3 *outColor,
46  float *outW)
47 {
48  float cellPosition = floorf(w);
49  float localPosition = w - cellPosition;
50 
51  float minDistance = 8.0f;
52  float targetOffset = 0.0f;
53  float targetPosition = 0.0f;
54  for (int i = -1; i <= 1; i++) {
55  float cellOffset = i;
56  float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
57  float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
58  if (distanceToPoint < minDistance) {
59  targetOffset = cellOffset;
60  minDistance = distanceToPoint;
61  targetPosition = pointPosition;
62  }
63  }
64  *outDistance = minDistance;
65  *outColor = hash_float_to_float3(cellPosition + targetOffset);
66  *outW = targetPosition + cellPosition;
67 }
68 
70  float smoothness,
71  float exponent,
72  float randomness,
74  float *outDistance,
75  float3 *outColor,
76  float *outW)
77 {
78  float cellPosition = floorf(w);
79  float localPosition = w - cellPosition;
80 
81  float smoothDistance = 8.0f;
82  float smoothPosition = 0.0f;
83  float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
84  for (int i = -2; i <= 2; i++) {
85  float cellOffset = i;
86  float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
87  float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
88  float h = smoothstep(
89  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
90  float correctionFactor = smoothness * h * (1.0f - h);
91  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
92  correctionFactor /= 1.0f + 3.0f * smoothness;
93  float3 cellColor = hash_float_to_float3(cellPosition + cellOffset);
94  smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
95  smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
96  }
97  *outDistance = smoothDistance;
98  *outColor = smoothColor;
99  *outW = cellPosition + smoothPosition;
100 }
101 
103  float exponent,
104  float randomness,
106  float *outDistance,
107  float3 *outColor,
108  float *outW)
109 {
110  float cellPosition = floorf(w);
111  float localPosition = w - cellPosition;
112 
113  float distanceF1 = 8.0f;
114  float distanceF2 = 8.0f;
115  float offsetF1 = 0.0f;
116  float positionF1 = 0.0f;
117  float offsetF2 = 0.0f;
118  float positionF2 = 0.0f;
119  for (int i = -1; i <= 1; i++) {
120  float cellOffset = i;
121  float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
122  float distanceToPoint = voronoi_distance_1d(pointPosition, localPosition, metric, exponent);
123  if (distanceToPoint < distanceF1) {
124  distanceF2 = distanceF1;
125  distanceF1 = distanceToPoint;
126  offsetF2 = offsetF1;
127  offsetF1 = cellOffset;
128  positionF2 = positionF1;
129  positionF1 = pointPosition;
130  }
131  else if (distanceToPoint < distanceF2) {
132  distanceF2 = distanceToPoint;
133  offsetF2 = cellOffset;
134  positionF2 = pointPosition;
135  }
136  }
137  *outDistance = distanceF2;
138  *outColor = hash_float_to_float3(cellPosition + offsetF2);
139  *outW = positionF2 + cellPosition;
140 }
141 
142 ccl_device void voronoi_distance_to_edge_1d(float w, float randomness, float *outDistance)
143 {
144  float cellPosition = floorf(w);
145  float localPosition = w - cellPosition;
146 
147  float midPointPosition = hash_float_to_float(cellPosition) * randomness;
148  float leftPointPosition = -1.0f + hash_float_to_float(cellPosition - 1.0f) * randomness;
149  float rightPointPosition = 1.0f + hash_float_to_float(cellPosition + 1.0f) * randomness;
150  float distanceToMidLeft = fabsf((midPointPosition + leftPointPosition) / 2.0f - localPosition);
151  float distanceToMidRight = fabsf((midPointPosition + rightPointPosition) / 2.0f - localPosition);
152 
153  *outDistance = min(distanceToMidLeft, distanceToMidRight);
154 }
155 
156 ccl_device void voronoi_n_sphere_radius_1d(float w, float randomness, float *outRadius)
157 {
158  float cellPosition = floorf(w);
159  float localPosition = w - cellPosition;
160 
161  float closestPoint = 0.0f;
162  float closestPointOffset = 0.0f;
163  float minDistance = 8.0f;
164  for (int i = -1; i <= 1; i++) {
165  float cellOffset = i;
166  float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
167  float distanceToPoint = fabsf(pointPosition - localPosition);
168  if (distanceToPoint < minDistance) {
169  minDistance = distanceToPoint;
170  closestPoint = pointPosition;
171  closestPointOffset = cellOffset;
172  }
173  }
174 
175  minDistance = 8.0f;
176  float closestPointToClosestPoint = 0.0f;
177  for (int i = -1; i <= 1; i++) {
178  if (i == 0) {
179  continue;
180  }
181  float cellOffset = i + closestPointOffset;
182  float pointPosition = cellOffset + hash_float_to_float(cellPosition + cellOffset) * randomness;
183  float distanceToPoint = fabsf(closestPoint - pointPosition);
184  if (distanceToPoint < minDistance) {
185  minDistance = distanceToPoint;
186  closestPointToClosestPoint = pointPosition;
187  }
188  }
189  *outRadius = fabsf(closestPointToClosestPoint - closestPoint) / 2.0f;
190 }
191 
192 /* **** 2D Voronoi **** */
193 
195  float2 b,
197  float exponent)
198 {
199  if (metric == NODE_VORONOI_EUCLIDEAN) {
200  return distance(a, b);
201  }
202  else if (metric == NODE_VORONOI_MANHATTAN) {
203  return fabsf(a.x - b.x) + fabsf(a.y - b.y);
204  }
205  else if (metric == NODE_VORONOI_CHEBYCHEV) {
206  return max(fabsf(a.x - b.x), fabsf(a.y - b.y));
207  }
208  else if (metric == NODE_VORONOI_MINKOWSKI) {
209  return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent),
210  1.0f / exponent);
211  }
212  else {
213  return 0.0f;
214  }
215 }
216 
218  float exponent,
219  float randomness,
221  float *outDistance,
222  float3 *outColor,
223  float2 *outPosition)
224 {
225  float2 cellPosition = floor(coord);
226  float2 localPosition = coord - cellPosition;
227 
228  float minDistance = 8.0f;
229  float2 targetOffset = make_float2(0.0f, 0.0f);
230  float2 targetPosition = make_float2(0.0f, 0.0f);
231  for (int j = -1; j <= 1; j++) {
232  for (int i = -1; i <= 1; i++) {
233  float2 cellOffset = make_float2(i, j);
234  float2 pointPosition = cellOffset +
235  hash_float2_to_float2(cellPosition + cellOffset) * randomness;
236  float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
237  if (distanceToPoint < minDistance) {
238  targetOffset = cellOffset;
239  minDistance = distanceToPoint;
240  targetPosition = pointPosition;
241  }
242  }
243  }
244  *outDistance = minDistance;
245  *outColor = hash_float2_to_float3(cellPosition + targetOffset);
246  *outPosition = targetPosition + cellPosition;
247 }
248 
250  float smoothness,
251  float exponent,
252  float randomness,
254  float *outDistance,
255  float3 *outColor,
256  float2 *outPosition)
257 {
258  float2 cellPosition = floor(coord);
259  float2 localPosition = coord - cellPosition;
260 
261  float smoothDistance = 8.0f;
262  float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
263  float2 smoothPosition = make_float2(0.0f, 0.0f);
264  for (int j = -2; j <= 2; j++) {
265  for (int i = -2; i <= 2; i++) {
266  float2 cellOffset = make_float2(i, j);
267  float2 pointPosition = cellOffset +
268  hash_float2_to_float2(cellPosition + cellOffset) * randomness;
269  float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
270  float h = smoothstep(
271  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
272  float correctionFactor = smoothness * h * (1.0f - h);
273  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
274  correctionFactor /= 1.0f + 3.0f * smoothness;
275  float3 cellColor = hash_float2_to_float3(cellPosition + cellOffset);
276  smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
277  smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
278  }
279  }
280  *outDistance = smoothDistance;
281  *outColor = smoothColor;
282  *outPosition = cellPosition + smoothPosition;
283 }
284 
286  float exponent,
287  float randomness,
289  float *outDistance,
290  float3 *outColor,
291  float2 *outPosition)
292 {
293  float2 cellPosition = floor(coord);
294  float2 localPosition = coord - cellPosition;
295 
296  float distanceF1 = 8.0f;
297  float distanceF2 = 8.0f;
298  float2 offsetF1 = make_float2(0.0f, 0.0f);
299  float2 positionF1 = make_float2(0.0f, 0.0f);
300  float2 offsetF2 = make_float2(0.0f, 0.0f);
301  float2 positionF2 = make_float2(0.0f, 0.0f);
302  for (int j = -1; j <= 1; j++) {
303  for (int i = -1; i <= 1; i++) {
304  float2 cellOffset = make_float2(i, j);
305  float2 pointPosition = cellOffset +
306  hash_float2_to_float2(cellPosition + cellOffset) * randomness;
307  float distanceToPoint = voronoi_distance_2d(pointPosition, localPosition, metric, exponent);
308  if (distanceToPoint < distanceF1) {
309  distanceF2 = distanceF1;
310  distanceF1 = distanceToPoint;
311  offsetF2 = offsetF1;
312  offsetF1 = cellOffset;
313  positionF2 = positionF1;
314  positionF1 = pointPosition;
315  }
316  else if (distanceToPoint < distanceF2) {
317  distanceF2 = distanceToPoint;
318  offsetF2 = cellOffset;
319  positionF2 = pointPosition;
320  }
321  }
322  }
323  *outDistance = distanceF2;
324  *outColor = hash_float2_to_float3(cellPosition + offsetF2);
325  *outPosition = positionF2 + cellPosition;
326 }
327 
328 ccl_device void voronoi_distance_to_edge_2d(float2 coord, float randomness, float *outDistance)
329 {
330  float2 cellPosition = floor(coord);
331  float2 localPosition = coord - cellPosition;
332 
333  float2 vectorToClosest = make_float2(0.0f, 0.0f);
334  float minDistance = 8.0f;
335  for (int j = -1; j <= 1; j++) {
336  for (int i = -1; i <= 1; i++) {
337  float2 cellOffset = make_float2(i, j);
338  float2 vectorToPoint = cellOffset +
339  hash_float2_to_float2(cellPosition + cellOffset) * randomness -
340  localPosition;
341  float distanceToPoint = dot(vectorToPoint, vectorToPoint);
342  if (distanceToPoint < minDistance) {
343  minDistance = distanceToPoint;
344  vectorToClosest = vectorToPoint;
345  }
346  }
347  }
348 
349  minDistance = 8.0f;
350  for (int j = -1; j <= 1; j++) {
351  for (int i = -1; i <= 1; i++) {
352  float2 cellOffset = make_float2(i, j);
353  float2 vectorToPoint = cellOffset +
354  hash_float2_to_float2(cellPosition + cellOffset) * randomness -
355  localPosition;
356  float2 perpendicularToEdge = vectorToPoint - vectorToClosest;
357  if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
358  float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
359  normalize(perpendicularToEdge));
360  minDistance = min(minDistance, distanceToEdge);
361  }
362  }
363  }
364  *outDistance = minDistance;
365 }
366 
367 ccl_device void voronoi_n_sphere_radius_2d(float2 coord, float randomness, float *outRadius)
368 {
369  float2 cellPosition = floor(coord);
370  float2 localPosition = coord - cellPosition;
371 
372  float2 closestPoint = make_float2(0.0f, 0.0f);
373  float2 closestPointOffset = make_float2(0.0f, 0.0f);
374  float minDistance = 8.0f;
375  for (int j = -1; j <= 1; j++) {
376  for (int i = -1; i <= 1; i++) {
377  float2 cellOffset = make_float2(i, j);
378  float2 pointPosition = cellOffset +
379  hash_float2_to_float2(cellPosition + cellOffset) * randomness;
380  float distanceToPoint = distance(pointPosition, localPosition);
381  if (distanceToPoint < minDistance) {
382  minDistance = distanceToPoint;
383  closestPoint = pointPosition;
384  closestPointOffset = cellOffset;
385  }
386  }
387  }
388 
389  minDistance = 8.0f;
390  float2 closestPointToClosestPoint = make_float2(0.0f, 0.0f);
391  for (int j = -1; j <= 1; j++) {
392  for (int i = -1; i <= 1; i++) {
393  if (i == 0 && j == 0) {
394  continue;
395  }
396  float2 cellOffset = make_float2(i, j) + closestPointOffset;
397  float2 pointPosition = cellOffset +
398  hash_float2_to_float2(cellPosition + cellOffset) * randomness;
399  float distanceToPoint = distance(closestPoint, pointPosition);
400  if (distanceToPoint < minDistance) {
401  minDistance = distanceToPoint;
402  closestPointToClosestPoint = pointPosition;
403  }
404  }
405  }
406  *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
407 }
408 
409 /* **** 3D Voronoi **** */
410 
412  float3 b,
414  float exponent)
415 {
416  if (metric == NODE_VORONOI_EUCLIDEAN) {
417  return distance(a, b);
418  }
419  else if (metric == NODE_VORONOI_MANHATTAN) {
420  return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z);
421  }
422  else if (metric == NODE_VORONOI_CHEBYCHEV) {
423  return max(fabsf(a.x - b.x), max(fabsf(a.y - b.y), fabsf(a.z - b.z)));
424  }
425  else if (metric == NODE_VORONOI_MINKOWSKI) {
426  return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent) +
427  powf(fabsf(a.z - b.z), exponent),
428  1.0f / exponent);
429  }
430  else {
431  return 0.0f;
432  }
433 }
434 
436  float exponent,
437  float randomness,
439  float *outDistance,
440  float3 *outColor,
441  float3 *outPosition)
442 {
443  float3 cellPosition = floor(coord);
444  float3 localPosition = coord - cellPosition;
445 
446  float minDistance = 8.0f;
447  float3 targetOffset = make_float3(0.0f, 0.0f, 0.0f);
448  float3 targetPosition = make_float3(0.0f, 0.0f, 0.0f);
449  for (int k = -1; k <= 1; k++) {
450  for (int j = -1; j <= 1; j++) {
451  for (int i = -1; i <= 1; i++) {
452  float3 cellOffset = make_float3(i, j, k);
453  float3 pointPosition = cellOffset +
454  hash_float3_to_float3(cellPosition + cellOffset) * randomness;
455  float distanceToPoint = voronoi_distance_3d(
456  pointPosition, localPosition, metric, exponent);
457  if (distanceToPoint < minDistance) {
458  targetOffset = cellOffset;
459  minDistance = distanceToPoint;
460  targetPosition = pointPosition;
461  }
462  }
463  }
464  }
465  *outDistance = minDistance;
466  *outColor = hash_float3_to_float3(cellPosition + targetOffset);
467  *outPosition = targetPosition + cellPosition;
468 }
469 
471  float smoothness,
472  float exponent,
473  float randomness,
475  float *outDistance,
476  float3 *outColor,
477  float3 *outPosition)
478 {
479  float3 cellPosition = floor(coord);
480  float3 localPosition = coord - cellPosition;
481 
482  float smoothDistance = 8.0f;
483  float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
484  float3 smoothPosition = make_float3(0.0f, 0.0f, 0.0f);
485  for (int k = -2; k <= 2; k++) {
486  for (int j = -2; j <= 2; j++) {
487  for (int i = -2; i <= 2; i++) {
488  float3 cellOffset = make_float3(i, j, k);
489  float3 pointPosition = cellOffset +
490  hash_float3_to_float3(cellPosition + cellOffset) * randomness;
491  float distanceToPoint = voronoi_distance_3d(
492  pointPosition, localPosition, metric, exponent);
493  float h = smoothstep(
494  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
495  float correctionFactor = smoothness * h * (1.0f - h);
496  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
497  correctionFactor /= 1.0f + 3.0f * smoothness;
498  float3 cellColor = hash_float3_to_float3(cellPosition + cellOffset);
499  smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
500  smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
501  }
502  }
503  }
504  *outDistance = smoothDistance;
505  *outColor = smoothColor;
506  *outPosition = cellPosition + smoothPosition;
507 }
508 
510  float exponent,
511  float randomness,
513  float *outDistance,
514  float3 *outColor,
515  float3 *outPosition)
516 {
517  float3 cellPosition = floor(coord);
518  float3 localPosition = coord - cellPosition;
519 
520  float distanceF1 = 8.0f;
521  float distanceF2 = 8.0f;
522  float3 offsetF1 = make_float3(0.0f, 0.0f, 0.0f);
523  float3 positionF1 = make_float3(0.0f, 0.0f, 0.0f);
524  float3 offsetF2 = make_float3(0.0f, 0.0f, 0.0f);
525  float3 positionF2 = make_float3(0.0f, 0.0f, 0.0f);
526  for (int k = -1; k <= 1; k++) {
527  for (int j = -1; j <= 1; j++) {
528  for (int i = -1; i <= 1; i++) {
529  float3 cellOffset = make_float3(i, j, k);
530  float3 pointPosition = cellOffset +
531  hash_float3_to_float3(cellPosition + cellOffset) * randomness;
532  float distanceToPoint = voronoi_distance_3d(
533  pointPosition, localPosition, metric, exponent);
534  if (distanceToPoint < distanceF1) {
535  distanceF2 = distanceF1;
536  distanceF1 = distanceToPoint;
537  offsetF2 = offsetF1;
538  offsetF1 = cellOffset;
539  positionF2 = positionF1;
540  positionF1 = pointPosition;
541  }
542  else if (distanceToPoint < distanceF2) {
543  distanceF2 = distanceToPoint;
544  offsetF2 = cellOffset;
545  positionF2 = pointPosition;
546  }
547  }
548  }
549  }
550  *outDistance = distanceF2;
551  *outColor = hash_float3_to_float3(cellPosition + offsetF2);
552  *outPosition = positionF2 + cellPosition;
553 }
554 
555 ccl_device void voronoi_distance_to_edge_3d(float3 coord, float randomness, float *outDistance)
556 {
557  float3 cellPosition = floor(coord);
558  float3 localPosition = coord - cellPosition;
559 
560  float3 vectorToClosest = make_float3(0.0f, 0.0f, 0.0f);
561  float minDistance = 8.0f;
562  for (int k = -1; k <= 1; k++) {
563  for (int j = -1; j <= 1; j++) {
564  for (int i = -1; i <= 1; i++) {
565  float3 cellOffset = make_float3(i, j, k);
566  float3 vectorToPoint = cellOffset +
567  hash_float3_to_float3(cellPosition + cellOffset) * randomness -
568  localPosition;
569  float distanceToPoint = dot(vectorToPoint, vectorToPoint);
570  if (distanceToPoint < minDistance) {
571  minDistance = distanceToPoint;
572  vectorToClosest = vectorToPoint;
573  }
574  }
575  }
576  }
577 
578  minDistance = 8.0f;
579  for (int k = -1; k <= 1; k++) {
580  for (int j = -1; j <= 1; j++) {
581  for (int i = -1; i <= 1; i++) {
582  float3 cellOffset = make_float3(i, j, k);
583  float3 vectorToPoint = cellOffset +
584  hash_float3_to_float3(cellPosition + cellOffset) * randomness -
585  localPosition;
586  float3 perpendicularToEdge = vectorToPoint - vectorToClosest;
587  if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
588  float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
589  normalize(perpendicularToEdge));
590  minDistance = min(minDistance, distanceToEdge);
591  }
592  }
593  }
594  }
595  *outDistance = minDistance;
596 }
597 
598 ccl_device void voronoi_n_sphere_radius_3d(float3 coord, float randomness, float *outRadius)
599 {
600  float3 cellPosition = floor(coord);
601  float3 localPosition = coord - cellPosition;
602 
603  float3 closestPoint = make_float3(0.0f, 0.0f, 0.0f);
604  float3 closestPointOffset = make_float3(0.0f, 0.0f, 0.0f);
605  float minDistance = 8.0f;
606  for (int k = -1; k <= 1; k++) {
607  for (int j = -1; j <= 1; j++) {
608  for (int i = -1; i <= 1; i++) {
609  float3 cellOffset = make_float3(i, j, k);
610  float3 pointPosition = cellOffset +
611  hash_float3_to_float3(cellPosition + cellOffset) * randomness;
612  float distanceToPoint = distance(pointPosition, localPosition);
613  if (distanceToPoint < minDistance) {
614  minDistance = distanceToPoint;
615  closestPoint = pointPosition;
616  closestPointOffset = cellOffset;
617  }
618  }
619  }
620  }
621 
622  minDistance = 8.0f;
623  float3 closestPointToClosestPoint = make_float3(0.0f, 0.0f, 0.0f);
624  for (int k = -1; k <= 1; k++) {
625  for (int j = -1; j <= 1; j++) {
626  for (int i = -1; i <= 1; i++) {
627  if (i == 0 && j == 0 && k == 0) {
628  continue;
629  }
630  float3 cellOffset = make_float3(i, j, k) + closestPointOffset;
631  float3 pointPosition = cellOffset +
632  hash_float3_to_float3(cellPosition + cellOffset) * randomness;
633  float distanceToPoint = distance(closestPoint, pointPosition);
634  if (distanceToPoint < minDistance) {
635  minDistance = distanceToPoint;
636  closestPointToClosestPoint = pointPosition;
637  }
638  }
639  }
640  }
641  *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
642 }
643 
644 /* **** 4D Voronoi **** */
645 
647  float4 b,
649  float exponent)
650 {
651  if (metric == NODE_VORONOI_EUCLIDEAN) {
652  return distance(a, b);
653  }
654  else if (metric == NODE_VORONOI_MANHATTAN) {
655  return fabsf(a.x - b.x) + fabsf(a.y - b.y) + fabsf(a.z - b.z) + fabsf(a.w - b.w);
656  }
657  else if (metric == NODE_VORONOI_CHEBYCHEV) {
658  return max(fabsf(a.x - b.x), max(fabsf(a.y - b.y), max(fabsf(a.z - b.z), fabsf(a.w - b.w))));
659  }
660  else if (metric == NODE_VORONOI_MINKOWSKI) {
661  return powf(powf(fabsf(a.x - b.x), exponent) + powf(fabsf(a.y - b.y), exponent) +
662  powf(fabsf(a.z - b.z), exponent) + powf(fabsf(a.w - b.w), exponent),
663  1.0f / exponent);
664  }
665  else {
666  return 0.0f;
667  }
668 }
669 
670 ccl_device void voronoi_f1_4d(float4 coord,
671  float exponent,
672  float randomness,
674  float *outDistance,
675  float3 *outColor,
676  float4 *outPosition)
677 {
678  float4 cellPosition = floor(coord);
679  float4 localPosition = coord - cellPosition;
680 
681  float minDistance = 8.0f;
682  float4 targetOffset = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
683  float4 targetPosition = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
684  for (int u = -1; u <= 1; u++) {
685  for (int k = -1; k <= 1; k++) {
686  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
687  {
688  for (int i = -1; i <= 1; i++) {
689  float4 cellOffset = make_float4(i, j, k, u);
690  float4 pointPosition = cellOffset +
691  hash_float4_to_float4(cellPosition + cellOffset) * randomness;
692  float distanceToPoint = voronoi_distance_4d(
693  pointPosition, localPosition, metric, exponent);
694  if (distanceToPoint < minDistance) {
695  targetOffset = cellOffset;
696  minDistance = distanceToPoint;
697  targetPosition = pointPosition;
698  }
699  }
700  }
701  }
702  }
703  *outDistance = minDistance;
704  *outColor = hash_float4_to_float3(cellPosition + targetOffset);
705  *outPosition = targetPosition + cellPosition;
706 }
707 
709  float smoothness,
710  float exponent,
711  float randomness,
713  float *outDistance,
714  float3 *outColor,
715  float4 *outPosition)
716 {
717  float4 cellPosition = floor(coord);
718  float4 localPosition = coord - cellPosition;
719 
720  float smoothDistance = 8.0f;
721  float3 smoothColor = make_float3(0.0f, 0.0f, 0.0f);
722  float4 smoothPosition = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
723  for (int u = -2; u <= 2; u++) {
724  for (int k = -2; k <= 2; k++) {
725  ccl_loop_no_unroll for (int j = -2; j <= 2; j++)
726  {
727  for (int i = -2; i <= 2; i++) {
728  float4 cellOffset = make_float4(i, j, k, u);
729  float4 pointPosition = cellOffset +
730  hash_float4_to_float4(cellPosition + cellOffset) * randomness;
731  float distanceToPoint = voronoi_distance_4d(
732  pointPosition, localPosition, metric, exponent);
733  float h = smoothstep(
734  0.0f, 1.0f, 0.5f + 0.5f * (smoothDistance - distanceToPoint) / smoothness);
735  float correctionFactor = smoothness * h * (1.0f - h);
736  smoothDistance = mix(smoothDistance, distanceToPoint, h) - correctionFactor;
737  correctionFactor /= 1.0f + 3.0f * smoothness;
738  float3 cellColor = hash_float4_to_float3(cellPosition + cellOffset);
739  smoothColor = mix(smoothColor, cellColor, h) - correctionFactor;
740  smoothPosition = mix(smoothPosition, pointPosition, h) - correctionFactor;
741  }
742  }
743  }
744  }
745  *outDistance = smoothDistance;
746  *outColor = smoothColor;
747  *outPosition = cellPosition + smoothPosition;
748 }
749 
750 ccl_device void voronoi_f2_4d(float4 coord,
751  float exponent,
752  float randomness,
754  float *outDistance,
755  float3 *outColor,
756  float4 *outPosition)
757 {
758  float4 cellPosition = floor(coord);
759  float4 localPosition = coord - cellPosition;
760 
761  float distanceF1 = 8.0f;
762  float distanceF2 = 8.0f;
763  float4 offsetF1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
764  float4 positionF1 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
765  float4 offsetF2 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
766  float4 positionF2 = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
767  for (int u = -1; u <= 1; u++) {
768  for (int k = -1; k <= 1; k++) {
769  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
770  {
771  for (int i = -1; i <= 1; i++) {
772  float4 cellOffset = make_float4(i, j, k, u);
773  float4 pointPosition = cellOffset +
774  hash_float4_to_float4(cellPosition + cellOffset) * randomness;
775  float distanceToPoint = voronoi_distance_4d(
776  pointPosition, localPosition, metric, exponent);
777  if (distanceToPoint < distanceF1) {
778  distanceF2 = distanceF1;
779  distanceF1 = distanceToPoint;
780  offsetF2 = offsetF1;
781  offsetF1 = cellOffset;
782  positionF2 = positionF1;
783  positionF1 = pointPosition;
784  }
785  else if (distanceToPoint < distanceF2) {
786  distanceF2 = distanceToPoint;
787  offsetF2 = cellOffset;
788  positionF2 = pointPosition;
789  }
790  }
791  }
792  }
793  }
794  *outDistance = distanceF2;
795  *outColor = hash_float4_to_float3(cellPosition + offsetF2);
796  *outPosition = positionF2 + cellPosition;
797 }
798 
799 ccl_device void voronoi_distance_to_edge_4d(float4 coord, float randomness, float *outDistance)
800 {
801  float4 cellPosition = floor(coord);
802  float4 localPosition = coord - cellPosition;
803 
804  float4 vectorToClosest = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
805  float minDistance = 8.0f;
806  for (int u = -1; u <= 1; u++) {
807  for (int k = -1; k <= 1; k++) {
808  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
809  {
810  for (int i = -1; i <= 1; i++) {
811  float4 cellOffset = make_float4(i, j, k, u);
812  float4 vectorToPoint = cellOffset +
813  hash_float4_to_float4(cellPosition + cellOffset) * randomness -
814  localPosition;
815  float distanceToPoint = dot(vectorToPoint, vectorToPoint);
816  if (distanceToPoint < minDistance) {
817  minDistance = distanceToPoint;
818  vectorToClosest = vectorToPoint;
819  }
820  }
821  }
822  }
823  }
824 
825  minDistance = 8.0f;
826  for (int u = -1; u <= 1; u++) {
827  for (int k = -1; k <= 1; k++) {
828  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
829  {
830  for (int i = -1; i <= 1; i++) {
831  float4 cellOffset = make_float4(i, j, k, u);
832  float4 vectorToPoint = cellOffset +
833  hash_float4_to_float4(cellPosition + cellOffset) * randomness -
834  localPosition;
835  float4 perpendicularToEdge = vectorToPoint - vectorToClosest;
836  if (dot(perpendicularToEdge, perpendicularToEdge) > 0.0001f) {
837  float distanceToEdge = dot((vectorToClosest + vectorToPoint) / 2.0f,
838  normalize(perpendicularToEdge));
839  minDistance = min(minDistance, distanceToEdge);
840  }
841  }
842  }
843  }
844  }
845  *outDistance = minDistance;
846 }
847 
848 ccl_device void voronoi_n_sphere_radius_4d(float4 coord, float randomness, float *outRadius)
849 {
850  float4 cellPosition = floor(coord);
851  float4 localPosition = coord - cellPosition;
852 
853  float4 closestPoint = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
854  float4 closestPointOffset = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
855  float minDistance = 8.0f;
856  for (int u = -1; u <= 1; u++) {
857  for (int k = -1; k <= 1; k++) {
858  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
859  {
860  for (int i = -1; i <= 1; i++) {
861  float4 cellOffset = make_float4(i, j, k, u);
862  float4 pointPosition = cellOffset +
863  hash_float4_to_float4(cellPosition + cellOffset) * randomness;
864  float distanceToPoint = distance(pointPosition, localPosition);
865  if (distanceToPoint < minDistance) {
866  minDistance = distanceToPoint;
867  closestPoint = pointPosition;
868  closestPointOffset = cellOffset;
869  }
870  }
871  }
872  }
873  }
874 
875  minDistance = 8.0f;
876  float4 closestPointToClosestPoint = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
877  for (int u = -1; u <= 1; u++) {
878  for (int k = -1; k <= 1; k++) {
879  ccl_loop_no_unroll for (int j = -1; j <= 1; j++)
880  {
881  for (int i = -1; i <= 1; i++) {
882  if (i == 0 && j == 0 && k == 0 && u == 0) {
883  continue;
884  }
885  float4 cellOffset = make_float4(i, j, k, u) + closestPointOffset;
886  float4 pointPosition = cellOffset +
887  hash_float4_to_float4(cellPosition + cellOffset) * randomness;
888  float distanceToPoint = distance(closestPoint, pointPosition);
889  if (distanceToPoint < minDistance) {
890  minDistance = distanceToPoint;
891  closestPointToClosestPoint = pointPosition;
892  }
893  }
894  }
895  }
896  }
897  *outRadius = distance(closestPointToClosestPoint, closestPoint) / 2.0f;
898 }
899 
900 ccl_device void svm_node_tex_voronoi(KernelGlobals *kg,
901  ShaderData *sd,
902  float *stack,
903  uint dimensions,
904  uint feature,
905  uint metric,
906  int *offset)
907 {
908  uint4 stack_offsets = read_node(kg, offset);
909  uint4 defaults = read_node(kg, offset);
910 
911  uint coord_stack_offset, w_stack_offset, scale_stack_offset, smoothness_stack_offset;
912  uint exponent_stack_offset, randomness_stack_offset, distance_out_stack_offset,
913  color_out_stack_offset;
914  uint position_out_stack_offset, w_out_stack_offset, radius_out_stack_offset;
915 
916  svm_unpack_node_uchar4(stack_offsets.x,
917  &coord_stack_offset,
918  &w_stack_offset,
919  &scale_stack_offset,
920  &smoothness_stack_offset);
921  svm_unpack_node_uchar4(stack_offsets.y,
922  &exponent_stack_offset,
923  &randomness_stack_offset,
924  &distance_out_stack_offset,
925  &color_out_stack_offset);
927  stack_offsets.z, &position_out_stack_offset, &w_out_stack_offset, &radius_out_stack_offset);
928 
929  float3 coord = stack_load_float3(stack, coord_stack_offset);
930  float w = stack_load_float_default(stack, w_stack_offset, stack_offsets.w);
931  float scale = stack_load_float_default(stack, scale_stack_offset, defaults.x);
932  float smoothness = stack_load_float_default(stack, smoothness_stack_offset, defaults.y);
933  float exponent = stack_load_float_default(stack, exponent_stack_offset, defaults.z);
934  float randomness = stack_load_float_default(stack, randomness_stack_offset, defaults.w);
935 
936  NodeVoronoiFeature voronoi_feature = (NodeVoronoiFeature)feature;
937  NodeVoronoiDistanceMetric voronoi_metric = (NodeVoronoiDistanceMetric)metric;
938 
939  float distance_out = 0.0f, w_out = 0.0f, radius_out = 0.0f;
940  float3 color_out = make_float3(0.0f, 0.0f, 0.0f);
941  float3 position_out = make_float3(0.0f, 0.0f, 0.0f);
942 
943  randomness = clamp(randomness, 0.0f, 1.0f);
944  smoothness = clamp(smoothness / 2.0f, 0.0f, 0.5f);
945 
946  w *= scale;
947  coord *= scale;
948 
949  switch (dimensions) {
950  case 1: {
951  switch (voronoi_feature) {
952  case NODE_VORONOI_F1:
954  w, exponent, randomness, voronoi_metric, &distance_out, &color_out, &w_out);
955  break;
958  smoothness,
959  exponent,
960  randomness,
961  voronoi_metric,
962  &distance_out,
963  &color_out,
964  &w_out);
965  break;
966  case NODE_VORONOI_F2:
968  w, exponent, randomness, voronoi_metric, &distance_out, &color_out, &w_out);
969  break;
971  voronoi_distance_to_edge_1d(w, randomness, &distance_out);
972  break;
974  voronoi_n_sphere_radius_1d(w, randomness, &radius_out);
975  break;
976  default:
977  kernel_assert(0);
978  }
979  w_out = safe_divide(w_out, scale);
980  break;
981  }
982  case 2: {
983  float2 coord_2d = make_float2(coord.x, coord.y);
984  float2 position_out_2d;
985  switch (voronoi_feature) {
986  case NODE_VORONOI_F1:
987  voronoi_f1_2d(coord_2d,
988  exponent,
989  randomness,
990  voronoi_metric,
991  &distance_out,
992  &color_out,
993  &position_out_2d);
994  break;
995 #if NODES_FEATURE(NODE_FEATURE_VORONOI_EXTRA)
997  voronoi_smooth_f1_2d(coord_2d,
998  smoothness,
999  exponent,
1000  randomness,
1001  voronoi_metric,
1002  &distance_out,
1003  &color_out,
1004  &position_out_2d);
1005  break;
1006 #endif
1007  case NODE_VORONOI_F2:
1008  voronoi_f2_2d(coord_2d,
1009  exponent,
1010  randomness,
1011  voronoi_metric,
1012  &distance_out,
1013  &color_out,
1014  &position_out_2d);
1015  break;
1017  voronoi_distance_to_edge_2d(coord_2d, randomness, &distance_out);
1018  break;
1020  voronoi_n_sphere_radius_2d(coord_2d, randomness, &radius_out);
1021  break;
1022  default:
1023  kernel_assert(0);
1024  }
1025  position_out_2d = safe_divide_float2_float(position_out_2d, scale);
1026  position_out = make_float3(position_out_2d.x, position_out_2d.y, 0.0f);
1027  break;
1028  }
1029  case 3: {
1030  switch (voronoi_feature) {
1031  case NODE_VORONOI_F1:
1032  voronoi_f1_3d(coord,
1033  exponent,
1034  randomness,
1035  voronoi_metric,
1036  &distance_out,
1037  &color_out,
1038  &position_out);
1039  break;
1040 #if NODES_FEATURE(NODE_FEATURE_VORONOI_EXTRA)
1042  voronoi_smooth_f1_3d(coord,
1043  smoothness,
1044  exponent,
1045  randomness,
1046  voronoi_metric,
1047  &distance_out,
1048  &color_out,
1049  &position_out);
1050  break;
1051 #endif
1052  case NODE_VORONOI_F2:
1053  voronoi_f2_3d(coord,
1054  exponent,
1055  randomness,
1056  voronoi_metric,
1057  &distance_out,
1058  &color_out,
1059  &position_out);
1060  break;
1062  voronoi_distance_to_edge_3d(coord, randomness, &distance_out);
1063  break;
1065  voronoi_n_sphere_radius_3d(coord, randomness, &radius_out);
1066  break;
1067  default:
1068  kernel_assert(0);
1069  }
1070  position_out = safe_divide_float3_float(position_out, scale);
1071  break;
1072  }
1073 
1074 #if NODES_FEATURE(NODE_FEATURE_VORONOI_EXTRA)
1075  case 4: {
1076  float4 coord_4d = make_float4(coord.x, coord.y, coord.z, w);
1077  float4 position_out_4d;
1078  switch (voronoi_feature) {
1079  case NODE_VORONOI_F1:
1080  voronoi_f1_4d(coord_4d,
1081  exponent,
1082  randomness,
1083  voronoi_metric,
1084  &distance_out,
1085  &color_out,
1086  &position_out_4d);
1087  break;
1089  voronoi_smooth_f1_4d(coord_4d,
1090  smoothness,
1091  exponent,
1092  randomness,
1093  voronoi_metric,
1094  &distance_out,
1095  &color_out,
1096  &position_out_4d);
1097  break;
1098  case NODE_VORONOI_F2:
1099  voronoi_f2_4d(coord_4d,
1100  exponent,
1101  randomness,
1102  voronoi_metric,
1103  &distance_out,
1104  &color_out,
1105  &position_out_4d);
1106  break;
1108  voronoi_distance_to_edge_4d(coord_4d, randomness, &distance_out);
1109  break;
1111  voronoi_n_sphere_radius_4d(coord_4d, randomness, &radius_out);
1112  break;
1113  default:
1114  kernel_assert(0);
1115  }
1116  position_out_4d = safe_divide_float4_float(position_out_4d, scale);
1117  position_out = make_float3(position_out_4d.x, position_out_4d.y, position_out_4d.z);
1118  w_out = position_out_4d.w;
1119  break;
1120  }
1121 #endif
1122  default:
1123  kernel_assert(0);
1124  }
1125 
1126  if (stack_valid(distance_out_stack_offset))
1127  stack_store_float(stack, distance_out_stack_offset, distance_out);
1128  if (stack_valid(color_out_stack_offset))
1129  stack_store_float3(stack, color_out_stack_offset, color_out);
1130  if (stack_valid(position_out_stack_offset))
1131  stack_store_float3(stack, position_out_stack_offset, position_out);
1132  if (stack_valid(w_out_stack_offset))
1133  stack_store_float(stack, w_out_stack_offset, w_out);
1134  if (stack_valid(radius_out_stack_offset))
1135  stack_store_float(stack, radius_out_stack_offset, radius_out);
1136 }
1137 
MINLINE float safe_divide(float a, float b)
unsigned int uint
Definition: BLI_sys_types.h:83
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
CCL_NAMESPACE_BEGIN ccl_device_inline float3 stack_load_float3(float *stack, uint a)
ccl_device_inline uint4 read_node(KernelGlobals *kg, int *offset)
ccl_device_inline float stack_load_float_default(float *stack, uint a, uint value)
ccl_device_forceinline void svm_unpack_node_uchar3(uint i, uint *x, uint *y, uint *z)
ccl_device_inline void stack_store_float3(float *stack, uint a, float3 f)
ccl_device_forceinline void svm_unpack_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
ccl_device_inline void stack_store_float(float *stack, uint a, float f)
ccl_device_inline bool stack_valid(uint a)
#define kernel_assert(cond)
#define ccl_loop_no_unroll
#define ccl_device
#define powf(x, y)
#define CCL_NAMESPACE_END
#define make_float2(x, y)
#define floorf(x)
#define make_float4(x, y, z, w)
#define fabsf(x)
#define make_float3(x, y, z)
ShaderData
static unsigned a[3]
Definition: RandGen.cpp:92
float hash_float_to_float(float k)
Definition: node_hash.h:9
#define min(a, b)
Definition: sort.c:51
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
NodeVoronoiFeature
Definition: svm_types.h:445
@ NODE_VORONOI_SMOOTH_F1
Definition: svm_types.h:448
@ NODE_VORONOI_N_SPHERE_RADIUS
Definition: svm_types.h:450
@ NODE_VORONOI_F1
Definition: svm_types.h:446
@ NODE_VORONOI_F2
Definition: svm_types.h:447
@ NODE_VORONOI_DISTANCE_TO_EDGE
Definition: svm_types.h:449
NodeVoronoiDistanceMetric
Definition: svm_types.h:438
@ NODE_VORONOI_EUCLIDEAN
Definition: svm_types.h:439
@ NODE_VORONOI_MANHATTAN
Definition: svm_types.h:440
@ NODE_VORONOI_CHEBYCHEV
Definition: svm_types.h:441
@ NODE_VORONOI_MINKOWSKI
Definition: svm_types.h:442
ccl_device void voronoi_distance_to_edge_3d(float3 coord, float randomness, float *outDistance)
Definition: svm_voronoi.h:555
ccl_device void voronoi_f2_3d(float3 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float3 *outPosition)
Definition: svm_voronoi.h:509
ccl_device void voronoi_n_sphere_radius_1d(float w, float randomness, float *outRadius)
Definition: svm_voronoi.h:156
ccl_device float voronoi_distance_4d(float4 a, float4 b, NodeVoronoiDistanceMetric metric, float exponent)
Definition: svm_voronoi.h:646
ccl_device void voronoi_n_sphere_radius_4d(float4 coord, float randomness, float *outRadius)
Definition: svm_voronoi.h:848
ccl_device float voronoi_distance_2d(float2 a, float2 b, NodeVoronoiDistanceMetric metric, float exponent)
Definition: svm_voronoi.h:194
ccl_device void voronoi_distance_to_edge_1d(float w, float randomness, float *outDistance)
Definition: svm_voronoi.h:142
ccl_device void voronoi_n_sphere_radius_3d(float3 coord, float randomness, float *outRadius)
Definition: svm_voronoi.h:598
ccl_device void voronoi_distance_to_edge_2d(float2 coord, float randomness, float *outDistance)
Definition: svm_voronoi.h:328
ccl_device void voronoi_distance_to_edge_4d(float4 coord, float randomness, float *outDistance)
Definition: svm_voronoi.h:799
ccl_device void voronoi_f2_2d(float2 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float2 *outPosition)
Definition: svm_voronoi.h:285
ccl_device void voronoi_f1_1d(float w, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float *outW)
Definition: svm_voronoi.h:40
ccl_device void voronoi_f1_2d(float2 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float2 *outPosition)
Definition: svm_voronoi.h:217
ccl_device void voronoi_n_sphere_radius_2d(float2 coord, float randomness, float *outRadius)
Definition: svm_voronoi.h:367
ccl_device void voronoi_f1_4d(float4 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float4 *outPosition)
Definition: svm_voronoi.h:670
ccl_device void voronoi_smooth_f1_1d(float w, float smoothness, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float *outW)
Definition: svm_voronoi.h:69
ccl_device void voronoi_f2_4d(float4 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float4 *outPosition)
Definition: svm_voronoi.h:750
ccl_device void voronoi_f2_1d(float w, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float *outW)
Definition: svm_voronoi.h:102
ccl_device void voronoi_smooth_f1_4d(float4 coord, float smoothness, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float4 *outPosition)
Definition: svm_voronoi.h:708
ccl_device float voronoi_distance_3d(float3 a, float3 b, NodeVoronoiDistanceMetric metric, float exponent)
Definition: svm_voronoi.h:411
CCL_NAMESPACE_BEGIN ccl_device float voronoi_distance_1d(float a, float b, NodeVoronoiDistanceMetric metric, float exponent)
Definition: svm_voronoi.h:32
ccl_device void voronoi_smooth_f1_3d(float3 coord, float smoothness, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float3 *outPosition)
Definition: svm_voronoi.h:470
ccl_device void voronoi_smooth_f1_2d(float2 coord, float smoothness, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float2 *outPosition)
Definition: svm_voronoi.h:249
ccl_device void svm_node_tex_voronoi(KernelGlobals *kg, ShaderData *sd, float *stack, uint dimensions, uint feature, uint metric, int *offset)
Definition: svm_voronoi.h:900
ccl_device void voronoi_f1_3d(float3 coord, float exponent, float randomness, NodeVoronoiDistanceMetric metric, float *outDistance, float3 *outColor, float3 *outPosition)
Definition: svm_voronoi.h:435
float max
ccl_device_inline float3 hash_float_to_float3(float k)
Definition: util_hash.h:197
ccl_device_inline float3 hash_float4_to_float3(float4 k)
Definition: util_hash.h:211
ccl_device_inline float3 hash_float2_to_float3(float2 k)
Definition: util_hash.h:204
ccl_device_inline float2 hash_float2_to_float2(float2 k)
Definition: util_hash.h:175
ccl_device_inline float4 hash_float4_to_float4(float4 k)
Definition: util_hash.h:187
ccl_device_inline float3 hash_float3_to_float3(float3 k)
Definition: util_hash.h:180
#define mix(a, b, c)
Definition: util_hash.h:30
ccl_device_inline float smoothstep(float edge0, float edge1, float x)
Definition: util_math.h:298
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float distance(const float2 &a, const float2 &b)
ccl_device_inline float2 normalize(const float2 &a)
ccl_device_inline float dot(const float2 &a, const float2 &b)
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float2 safe_divide_float2_float(const float2 a, const float b)
ccl_device_inline float3 safe_divide_float3_float(const float3 a, const float b)
ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b)