Blender  V3.3
node_shader_tex_voronoi.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
4 #include "node_shader_util.hh"
5 
6 #include "BLI_noise.hh"
7 
8 #include "UI_interface.h"
9 #include "UI_resources.h"
10 
12 
14 
16 {
17  b.is_function_node();
18  b.add_input<decl::Vector>(N_("Vector")).hide_value().implicit_field();
19  b.add_input<decl::Float>(N_("W")).min(-1000.0f).max(1000.0f).make_available([](bNode &node) {
20  /* Default to 1 instead of 4, because it is much faster. */
21  node_storage(node).dimensions = 1;
22  });
23  b.add_input<decl::Float>(N_("Scale")).min(-1000.0f).max(1000.0f).default_value(5.0f);
24  b.add_input<decl::Float>(N_("Smoothness"))
25  .min(0.0f)
26  .max(1.0f)
27  .default_value(1.0f)
28  .subtype(PROP_FACTOR)
29  .make_available([](bNode &node) { node_storage(node).feature = SHD_VORONOI_SMOOTH_F1; });
30  b.add_input<decl::Float>(N_("Exponent"))
31  .min(0.0f)
32  .max(32.0f)
33  .default_value(0.5f)
34  .make_available([](bNode &node) { node_storage(node).distance = SHD_VORONOI_MINKOWSKI; });
35  b.add_input<decl::Float>(N_("Randomness"))
36  .min(0.0f)
37  .max(1.0f)
38  .default_value(1.0f)
39  .subtype(PROP_FACTOR);
40  b.add_output<decl::Float>(N_("Distance")).no_muted_links();
41  b.add_output<decl::Color>(N_("Color")).no_muted_links();
42  b.add_output<decl::Vector>(N_("Position")).no_muted_links();
43  b.add_output<decl::Float>(N_("W")).no_muted_links().make_available([](bNode &node) {
44  /* Default to 1 instead of 4, because it is much faster. */
45  node_storage(node).dimensions = 1;
46  });
47  b.add_output<decl::Float>(N_("Radius")).no_muted_links().make_available([](bNode &node) {
48  node_storage(node).feature = SHD_VORONOI_N_SPHERE_RADIUS;
49  });
50 }
51 
53 {
54  uiItemR(layout, ptr, "voronoi_dimensions", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
55  uiItemR(layout, ptr, "feature", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
56  int feature = RNA_enum_get(ptr, "feature");
58  RNA_enum_get(ptr, "voronoi_dimensions") != 1) {
59  uiItemR(layout, ptr, "distance", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
60  }
61 }
62 
64 {
65  NodeTexVoronoi *tex = MEM_cnew<NodeTexVoronoi>(__func__);
67  BKE_texture_colormapping_default(&tex->base.color_mapping);
68  tex->dimensions = 3;
69  tex->distance = SHD_VORONOI_EUCLIDEAN;
70  tex->feature = SHD_VORONOI_F1;
71 
72  node->storage = tex;
73 }
74 
75 static const char *gpu_shader_get_name(const int feature, const int dimensions)
76 {
77  BLI_assert(feature >= 0 && feature < 5);
78  BLI_assert(dimensions > 0 && dimensions < 5);
79 
80  switch (feature) {
81  case SHD_VORONOI_F1:
82  return std::array{
83  "node_tex_voronoi_f1_1d",
84  "node_tex_voronoi_f1_2d",
85  "node_tex_voronoi_f1_3d",
86  "node_tex_voronoi_f1_4d",
87  }[dimensions - 1];
88  case SHD_VORONOI_F2:
89  return std::array{
90  "node_tex_voronoi_f2_1d",
91  "node_tex_voronoi_f2_2d",
92  "node_tex_voronoi_f2_3d",
93  "node_tex_voronoi_f2_4d",
94  }[dimensions - 1];
96  return std::array{
97  "node_tex_voronoi_smooth_f1_1d",
98  "node_tex_voronoi_smooth_f1_2d",
99  "node_tex_voronoi_smooth_f1_3d",
100  "node_tex_voronoi_smooth_f1_4d",
101  }[dimensions - 1];
103  return std::array{
104  "node_tex_voronoi_distance_to_edge_1d",
105  "node_tex_voronoi_distance_to_edge_2d",
106  "node_tex_voronoi_distance_to_edge_3d",
107  "node_tex_voronoi_distance_to_edge_4d",
108  }[dimensions - 1];
110  return std::array{
111  "node_tex_voronoi_n_sphere_radius_1d",
112  "node_tex_voronoi_n_sphere_radius_2d",
113  "node_tex_voronoi_n_sphere_radius_3d",
114  "node_tex_voronoi_n_sphere_radius_4d",
115  }[dimensions - 1];
116  }
117  return nullptr;
118 }
119 
121  bNode *node,
122  bNodeExecData *UNUSED(execdata),
123  GPUNodeStack *in,
124  GPUNodeStack *out)
125 {
126  node_shader_gpu_default_tex_coord(mat, node, &in[0].link);
128 
129  NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage;
130  float metric = tex->distance;
131 
132  const char *name = gpu_shader_get_name(tex->feature, tex->dimensions);
133 
134  return GPU_stack_link(mat, node, name, in, out, GPU_constant(&metric));
135 }
136 
138 {
139  bNodeSocket *inVectorSock = nodeFindSocket(node, SOCK_IN, "Vector");
140  bNodeSocket *inWSock = nodeFindSocket(node, SOCK_IN, "W");
141  bNodeSocket *inSmoothnessSock = nodeFindSocket(node, SOCK_IN, "Smoothness");
142  bNodeSocket *inExponentSock = nodeFindSocket(node, SOCK_IN, "Exponent");
143 
144  bNodeSocket *outDistanceSock = nodeFindSocket(node, SOCK_OUT, "Distance");
145  bNodeSocket *outColorSock = nodeFindSocket(node, SOCK_OUT, "Color");
146  bNodeSocket *outPositionSock = nodeFindSocket(node, SOCK_OUT, "Position");
147  bNodeSocket *outWSock = nodeFindSocket(node, SOCK_OUT, "W");
148  bNodeSocket *outRadiusSock = nodeFindSocket(node, SOCK_OUT, "Radius");
149 
150  const NodeTexVoronoi &storage = node_storage(*node);
151 
152  nodeSetSocketAvailability(ntree, inWSock, storage.dimensions == 1 || storage.dimensions == 4);
153  nodeSetSocketAvailability(ntree, inVectorSock, storage.dimensions != 1);
155  ntree,
156  inExponentSock,
157  storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
159  nodeSetSocketAvailability(ntree, inSmoothnessSock, storage.feature == SHD_VORONOI_SMOOTH_F1);
160 
162  ntree, outDistanceSock, storage.feature != SHD_VORONOI_N_SPHERE_RADIUS);
164  outColorSock,
168  outPositionSock,
171  storage.dimensions != 1);
173  outWSock,
176  (ELEM(storage.dimensions, 1, 4)));
178 }
179 
181 
183  private:
184  int dimensions_;
185  int feature_;
186 
187  public:
188  VoronoiMinowskiFunction(int dimensions, int feature) : dimensions_(dimensions), feature_(feature)
189  {
190  BLI_assert(dimensions >= 2 && dimensions <= 4);
191  BLI_assert(feature >= 0 && feature <= 2);
192  static std::array<fn::MFSignature, 9> signatures{
196 
200 
204  };
205  this->set_signature(&signatures[(dimensions - 1) + feature * 3 - 1]);
206  }
207 
208  static fn::MFSignature create_signature(int dimensions, int feature)
209  {
210  fn::MFSignatureBuilder signature{"voronoi_minowski"};
211 
212  if (ELEM(dimensions, 2, 3, 4)) {
213  signature.single_input<float3>("Vector");
214  }
215  if (ELEM(dimensions, 1, 4)) {
216  signature.single_input<float>("W");
217  }
218  signature.single_input<float>("Scale");
219  if (feature == SHD_VORONOI_SMOOTH_F1) {
220  signature.single_input<float>("Smoothness");
221  }
222  signature.single_input<float>("Exponent");
223  signature.single_input<float>("Randomness");
224  signature.single_output<float>("Distance");
225  signature.single_output<ColorGeometry4f>("Color");
226 
227  if (dimensions != 1) {
228  signature.single_output<float3>("Position");
229  }
230  if (ELEM(dimensions, 1, 4)) {
231  signature.single_output<float>("W");
232  }
233 
234  return signature.build();
235  }
236 
238  {
239  auto get_vector = [&](int param_index) -> VArray<float3> {
240  return params.readonly_single_input<float3>(param_index, "Vector");
241  };
242  auto get_w = [&](int param_index) -> VArray<float> {
243  return params.readonly_single_input<float>(param_index, "W");
244  };
245  auto get_scale = [&](int param_index) -> VArray<float> {
246  return params.readonly_single_input<float>(param_index, "Scale");
247  };
248  auto get_smoothness = [&](int param_index) -> VArray<float> {
249  return params.readonly_single_input<float>(param_index, "Smoothness");
250  };
251  auto get_exponent = [&](int param_index) -> VArray<float> {
252  return params.readonly_single_input<float>(param_index, "Exponent");
253  };
254  auto get_randomness = [&](int param_index) -> VArray<float> {
255  return params.readonly_single_input<float>(param_index, "Randomness");
256  };
257  auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
258  return params.uninitialized_single_output_if_required<float>(param_index, "Distance");
259  };
260  auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> {
261  return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color");
262  };
263  auto get_r_position = [&](int param_index) -> MutableSpan<float3> {
264  return params.uninitialized_single_output_if_required<float3>(param_index, "Position");
265  };
266  auto get_r_w = [&](int param_index) -> MutableSpan<float> {
267  return params.uninitialized_single_output_if_required<float>(param_index, "W");
268  };
269 
270  int param = 0;
271  switch (dimensions_) {
272  case 2: {
273  switch (feature_) {
274  case SHD_VORONOI_F1: {
275  const VArray<float3> &vector = get_vector(param++);
276  const VArray<float> &scale = get_scale(param++);
277  const VArray<float> &exponent = get_exponent(param++);
278  const VArray<float> &randomness = get_randomness(param++);
279  MutableSpan<float> r_distance = get_r_distance(param++);
280  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
281  MutableSpan<float3> r_position = get_r_position(param++);
282  const bool calc_distance = !r_distance.is_empty();
283  const bool calc_color = !r_color.is_empty();
284  const bool calc_position = !r_position.is_empty();
285  for (int64_t i : mask) {
286  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
287  float3 col;
288  float2 pos;
289  noise::voronoi_f1(float2(vector[i].x, vector[i].y) * scale[i],
290  exponent[i],
291  rand,
293  calc_distance ? &r_distance[i] : nullptr,
294  calc_color ? &col : nullptr,
295  calc_position ? &pos : nullptr);
296  if (calc_color) {
297  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
298  }
299  if (calc_position) {
300  pos = math::safe_divide(pos, scale[i]);
301  r_position[i] = float3(pos.x, pos.y, 0.0f);
302  }
303  }
304  break;
305  }
306  case SHD_VORONOI_F2: {
307  const VArray<float3> &vector = get_vector(param++);
308  const VArray<float> &scale = get_scale(param++);
309  const VArray<float> &exponent = get_exponent(param++);
310  const VArray<float> &randomness = get_randomness(param++);
311  MutableSpan<float> r_distance = get_r_distance(param++);
312  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
313  MutableSpan<float3> r_position = get_r_position(param++);
314  const bool calc_distance = !r_distance.is_empty();
315  const bool calc_color = !r_color.is_empty();
316  const bool calc_position = !r_position.is_empty();
317  for (int64_t i : mask) {
318  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
319  float3 col;
320  float2 pos;
321  noise::voronoi_f2(float2(vector[i].x, vector[i].y) * scale[i],
322  exponent[i],
323  rand,
325  calc_distance ? &r_distance[i] : nullptr,
326  calc_color ? &col : nullptr,
327  calc_position ? &pos : nullptr);
328  if (calc_color) {
329  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
330  }
331  if (calc_position) {
332  pos = math::safe_divide(pos, scale[i]);
333  r_position[i] = float3(pos.x, pos.y, 0.0f);
334  }
335  }
336  break;
337  }
338  case SHD_VORONOI_SMOOTH_F1: {
339  const VArray<float3> &vector = get_vector(param++);
340  const VArray<float> &scale = get_scale(param++);
341  const VArray<float> &smoothness = get_smoothness(param++);
342  const VArray<float> &exponent = get_exponent(param++);
343  const VArray<float> &randomness = get_randomness(param++);
344  MutableSpan<float> r_distance = get_r_distance(param++);
345  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
346  MutableSpan<float3> r_position = get_r_position(param++);
347  const bool calc_distance = !r_distance.is_empty();
348  const bool calc_color = !r_color.is_empty();
349  const bool calc_position = !r_position.is_empty();
350  for (int64_t i : mask) {
351  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
352  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
353  float3 col;
354  float2 pos;
355  noise::voronoi_smooth_f1(float2(vector[i].x, vector[i].y) * scale[i],
356  smth,
357  exponent[i],
358  rand,
360  calc_distance ? &r_distance[i] : nullptr,
361  calc_color ? &col : nullptr,
362  calc_position ? &pos : nullptr);
363  if (calc_color) {
364  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
365  }
366  if (calc_position) {
367  pos = math::safe_divide(pos, scale[i]);
368  r_position[i] = float3(pos.x, pos.y, 0.0f);
369  }
370  }
371  break;
372  }
373  }
374  break;
375  }
376  case 3: {
377  switch (feature_) {
378  case SHD_VORONOI_F1: {
379  const VArray<float3> &vector = get_vector(param++);
380  const VArray<float> &scale = get_scale(param++);
381  const VArray<float> &exponent = get_exponent(param++);
382  const VArray<float> &randomness = get_randomness(param++);
383  MutableSpan<float> r_distance = get_r_distance(param++);
384  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
385  MutableSpan<float3> r_position = get_r_position(param++);
386  const bool calc_distance = !r_distance.is_empty();
387  const bool calc_color = !r_color.is_empty();
388  const bool calc_position = !r_position.is_empty();
389  for (int64_t i : mask) {
390  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
391  float3 col;
392  noise::voronoi_f1(vector[i] * scale[i],
393  exponent[i],
394  rand,
396  calc_distance ? &r_distance[i] : nullptr,
397  calc_color ? &col : nullptr,
398  calc_position ? &r_position[i] : nullptr);
399  if (calc_color) {
400  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
401  }
402  if (calc_position) {
403  r_position[i] = math::safe_divide(r_position[i], scale[i]);
404  }
405  }
406  break;
407  }
408  case SHD_VORONOI_F2: {
409  const VArray<float3> &vector = get_vector(param++);
410  const VArray<float> &scale = get_scale(param++);
411  const VArray<float> &exponent = get_exponent(param++);
412  const VArray<float> &randomness = get_randomness(param++);
413  MutableSpan<float> r_distance = get_r_distance(param++);
414  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
415  MutableSpan<float3> r_position = get_r_position(param++);
416  const bool calc_distance = !r_distance.is_empty();
417  const bool calc_color = !r_color.is_empty();
418  const bool calc_position = !r_position.is_empty();
419  for (int64_t i : mask) {
420  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
421  float3 col;
422  noise::voronoi_f2(vector[i] * scale[i],
423  exponent[i],
424  rand,
426  calc_distance ? &r_distance[i] : nullptr,
427  calc_color ? &col : nullptr,
428  calc_position ? &r_position[i] : nullptr);
429  if (calc_color) {
430  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
431  }
432  if (calc_position) {
433  r_position[i] = math::safe_divide(r_position[i], scale[i]);
434  }
435  }
436  break;
437  }
438  case SHD_VORONOI_SMOOTH_F1: {
439  const VArray<float3> &vector = get_vector(param++);
440  const VArray<float> &scale = get_scale(param++);
441  const VArray<float> &smoothness = get_smoothness(param++);
442  const VArray<float> &exponent = get_exponent(param++);
443  const VArray<float> &randomness = get_randomness(param++);
444  MutableSpan<float> r_distance = get_r_distance(param++);
445  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
446  MutableSpan<float3> r_position = get_r_position(param++);
447  const bool calc_distance = !r_distance.is_empty();
448  const bool calc_color = !r_color.is_empty();
449  const bool calc_position = !r_position.is_empty();
450  for (int64_t i : mask) {
451  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
452  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
453  float3 col;
454  noise::voronoi_smooth_f1(vector[i] * scale[i],
455  smth,
456  exponent[i],
457  rand,
459  calc_distance ? &r_distance[i] : nullptr,
460  calc_color ? &col : nullptr,
461  calc_position ? &r_position[i] : nullptr);
462  if (calc_color) {
463  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
464  }
465  if (calc_position) {
466  r_position[i] = math::safe_divide(r_position[i], scale[i]);
467  }
468  }
469  break;
470  }
471  }
472  break;
473  }
474  case 4: {
475  switch (feature_) {
476  case SHD_VORONOI_F1: {
477  const VArray<float3> &vector = get_vector(param++);
478  const VArray<float> &w = get_w(param++);
479  const VArray<float> &scale = get_scale(param++);
480  const VArray<float> &exponent = get_exponent(param++);
481  const VArray<float> &randomness = get_randomness(param++);
482  MutableSpan<float> r_distance = get_r_distance(param++);
483  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
484  MutableSpan<float3> r_position = get_r_position(param++);
485  MutableSpan<float> r_w = get_r_w(param++);
486  const bool calc_distance = !r_distance.is_empty();
487  const bool calc_color = !r_color.is_empty();
488  const bool calc_position = !r_position.is_empty();
489  const bool calc_w = !r_w.is_empty();
490  for (int64_t i : mask) {
491  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
492  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
493  float3 col;
494  float4 pos;
496  exponent[i],
497  rand,
499  calc_distance ? &r_distance[i] : nullptr,
500  calc_color ? &col : nullptr,
501  calc_position || calc_w ? &pos : nullptr);
502  if (calc_color) {
503  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
504  }
505  if (calc_position || calc_w) {
506  pos = math::safe_divide(pos, scale[i]);
507  if (calc_position) {
508  r_position[i] = float3(pos.x, pos.y, pos.z);
509  }
510  if (calc_w) {
511  r_w[i] = pos.w;
512  }
513  }
514  }
515  break;
516  }
517  case SHD_VORONOI_F2: {
518  const VArray<float3> &vector = get_vector(param++);
519  const VArray<float> &w = get_w(param++);
520  const VArray<float> &scale = get_scale(param++);
521  const VArray<float> &exponent = get_exponent(param++);
522  const VArray<float> &randomness = get_randomness(param++);
523  MutableSpan<float> r_distance = get_r_distance(param++);
524  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
525  MutableSpan<float3> r_position = get_r_position(param++);
526  MutableSpan<float> r_w = get_r_w(param++);
527  const bool calc_distance = !r_distance.is_empty();
528  const bool calc_color = !r_color.is_empty();
529  const bool calc_position = !r_position.is_empty();
530  const bool calc_w = !r_w.is_empty();
531  for (int64_t i : mask) {
532  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
533  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
534  float3 col;
535  float4 pos;
537  exponent[i],
538  rand,
540  calc_distance ? &r_distance[i] : nullptr,
541  calc_color ? &col : nullptr,
542  calc_position || calc_w ? &pos : nullptr);
543  if (calc_color) {
544  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
545  }
546  if (calc_position || calc_w) {
547  pos = math::safe_divide(pos, scale[i]);
548  if (calc_position) {
549  r_position[i] = float3(pos.x, pos.y, pos.z);
550  }
551  if (calc_w) {
552  r_w[i] = pos.w;
553  }
554  }
555  }
556  break;
557  }
558  case SHD_VORONOI_SMOOTH_F1: {
559  const VArray<float3> &vector = get_vector(param++);
560  const VArray<float> &w = get_w(param++);
561  const VArray<float> &scale = get_scale(param++);
562  const VArray<float> &smoothness = get_smoothness(param++);
563  const VArray<float> &exponent = get_exponent(param++);
564  const VArray<float> &randomness = get_randomness(param++);
565  MutableSpan<float> r_distance = get_r_distance(param++);
566  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
567  MutableSpan<float3> r_position = get_r_position(param++);
568  MutableSpan<float> r_w = get_r_w(param++);
569  const bool calc_distance = !r_distance.is_empty();
570  const bool calc_color = !r_color.is_empty();
571  const bool calc_position = !r_position.is_empty();
572  const bool calc_w = !r_w.is_empty();
573  for (int64_t i : mask) {
574  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
575  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
576  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
577  float3 col;
578  float4 pos;
580  smth,
581  exponent[i],
582  rand,
584  calc_distance ? &r_distance[i] : nullptr,
585  calc_color ? &col : nullptr,
586  calc_position || calc_w ? &pos : nullptr);
587  if (calc_color) {
588  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
589  }
590  if (calc_position || calc_w) {
591  pos = math::safe_divide(pos, scale[i]);
592  if (calc_position) {
593  r_position[i] = float3(pos.x, pos.y, pos.z);
594  }
595  if (calc_w) {
596  r_w[i] = pos.w;
597  }
598  }
599  }
600  break;
601  }
602  }
603  break;
604  }
605  }
606  }
607 
609  {
611  }
612 };
613 
615  private:
616  int dimensions_;
617  int feature_;
618  int metric_;
619 
620  public:
621  VoronoiMetricFunction(int dimensions, int feature, int metric)
622  : dimensions_(dimensions), feature_(feature), metric_(metric)
623  {
624  BLI_assert(dimensions >= 1 && dimensions <= 4);
625  BLI_assert(feature >= 0 && feature <= 4);
626  static std::array<fn::MFSignature, 12> signatures{
631 
636 
641  };
642  this->set_signature(&signatures[dimensions + feature * 4 - 1]);
643  }
644 
645  static fn::MFSignature create_signature(int dimensions, int feature)
646  {
647  fn::MFSignatureBuilder signature{"voronoi_metric"};
648 
649  if (ELEM(dimensions, 2, 3, 4)) {
650  signature.single_input<float3>("Vector");
651  }
652  if (ELEM(dimensions, 1, 4)) {
653  signature.single_input<float>("W");
654  }
655  signature.single_input<float>("Scale");
656  if (feature == SHD_VORONOI_SMOOTH_F1) {
657  signature.single_input<float>("Smoothness");
658  }
659  signature.single_input<float>("Randomness");
660  signature.single_output<float>("Distance");
661  signature.single_output<ColorGeometry4f>("Color");
662 
663  if (dimensions != 1) {
664  signature.single_output<float3>("Position");
665  }
666  if (ELEM(dimensions, 1, 4)) {
667  signature.single_output<float>("W");
668  }
669 
670  return signature.build();
671  }
672 
674  {
675  auto get_vector = [&](int param_index) -> VArray<float3> {
676  return params.readonly_single_input<float3>(param_index, "Vector");
677  };
678  auto get_w = [&](int param_index) -> VArray<float> {
679  return params.readonly_single_input<float>(param_index, "W");
680  };
681  auto get_scale = [&](int param_index) -> VArray<float> {
682  return params.readonly_single_input<float>(param_index, "Scale");
683  };
684  auto get_smoothness = [&](int param_index) -> VArray<float> {
685  return params.readonly_single_input<float>(param_index, "Smoothness");
686  };
687  auto get_randomness = [&](int param_index) -> VArray<float> {
688  return params.readonly_single_input<float>(param_index, "Randomness");
689  };
690  auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
691  return params.uninitialized_single_output_if_required<float>(param_index, "Distance");
692  };
693  auto get_r_color = [&](int param_index) -> MutableSpan<ColorGeometry4f> {
694  return params.uninitialized_single_output_if_required<ColorGeometry4f>(param_index, "Color");
695  };
696  auto get_r_position = [&](int param_index) -> MutableSpan<float3> {
697  return params.uninitialized_single_output_if_required<float3>(param_index, "Position");
698  };
699  auto get_r_w = [&](int param_index) -> MutableSpan<float> {
700  return params.uninitialized_single_output_if_required<float>(param_index, "W");
701  };
702 
703  int param = 0;
704  switch (dimensions_) {
705  case 1: {
706  switch (feature_) {
707  case SHD_VORONOI_F1: {
708  const VArray<float> &w = get_w(param++);
709  const VArray<float> &scale = get_scale(param++);
710  const VArray<float> &randomness = get_randomness(param++);
711  MutableSpan<float> r_distance = get_r_distance(param++);
712  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
713  MutableSpan<float> r_w = get_r_w(param++);
714  const bool calc_distance = !r_distance.is_empty();
715  const bool calc_color = !r_color.is_empty();
716  const bool calc_w = !r_w.is_empty();
717  for (int64_t i : mask) {
718  const float p = w[i] * scale[i];
719  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
720  float3 col;
722  rand,
723  calc_distance ? &r_distance[i] : nullptr,
724  calc_color ? &col : nullptr,
725  calc_w ? &r_w[i] : nullptr);
726  if (calc_color) {
727  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
728  }
729  if (calc_w) {
730  r_w[i] = safe_divide(r_w[i], scale[i]);
731  }
732  }
733  break;
734  }
735  case SHD_VORONOI_F2: {
736  const VArray<float> &w = get_w(param++);
737  const VArray<float> &scale = get_scale(param++);
738  const VArray<float> &randomness = get_randomness(param++);
739  MutableSpan<float> r_distance = get_r_distance(param++);
740  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
741  MutableSpan<float> r_w = get_r_w(param++);
742  const bool calc_distance = !r_distance.is_empty();
743  const bool calc_color = !r_color.is_empty();
744  const bool calc_w = !r_w.is_empty();
745  for (int64_t i : mask) {
746  const float p = w[i] * scale[i];
747  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
748  float3 col;
750  rand,
751  calc_distance ? &r_distance[i] : nullptr,
752  calc_color ? &col : nullptr,
753  calc_w ? &r_w[i] : nullptr);
754  if (calc_color) {
755  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
756  }
757  if (calc_w) {
758  r_w[i] = safe_divide(r_w[i], scale[i]);
759  }
760  }
761  break;
762  }
763  case SHD_VORONOI_SMOOTH_F1: {
764  const VArray<float> &w = get_w(param++);
765  const VArray<float> &scale = get_scale(param++);
766  const VArray<float> &smoothness = get_smoothness(param++);
767  const VArray<float> &randomness = get_randomness(param++);
768  MutableSpan<float> r_distance = get_r_distance(param++);
769  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
770  MutableSpan<float> r_w = get_r_w(param++);
771  const bool calc_distance = !r_distance.is_empty();
772  const bool calc_color = !r_color.is_empty();
773  const bool calc_w = !r_w.is_empty();
774  for (int64_t i : mask) {
775  const float p = w[i] * scale[i];
776  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
777  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
778  float3 col;
780  smth,
781  rand,
782  calc_distance ? &r_distance[i] : nullptr,
783  calc_color ? &col : nullptr,
784  calc_w ? &r_w[i] : nullptr);
785  if (calc_color) {
786  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
787  }
788  if (calc_w) {
789  r_w[i] = safe_divide(r_w[i], scale[i]);
790  }
791  }
792  break;
793  }
794  }
795  break;
796  }
797  case 2: {
798  switch (feature_) {
799  case SHD_VORONOI_F1: {
800  const VArray<float3> &vector = get_vector(param++);
801  const VArray<float> &scale = get_scale(param++);
802  const VArray<float> &randomness = get_randomness(param++);
803  MutableSpan<float> r_distance = get_r_distance(param++);
804  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
805  MutableSpan<float3> r_position = get_r_position(param++);
806  const bool calc_distance = !r_distance.is_empty();
807  const bool calc_color = !r_color.is_empty();
808  const bool calc_position = !r_position.is_empty();
809  for (int64_t i : mask) {
810  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
811  float3 col;
812  float2 pos;
813  noise::voronoi_f1(float2(vector[i].x, vector[i].y) * scale[i],
814  0.0f,
815  rand,
816  metric_,
817  calc_distance ? &r_distance[i] : nullptr,
818  calc_color ? &col : nullptr,
819  calc_position ? &pos : nullptr);
820  if (calc_color) {
821  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
822  }
823  if (calc_position) {
824  pos = math::safe_divide(pos, scale[i]);
825  r_position[i] = float3(pos.x, pos.y, 0.0f);
826  }
827  }
828  break;
829  }
830  case SHD_VORONOI_F2: {
831  const VArray<float3> &vector = get_vector(param++);
832  const VArray<float> &scale = get_scale(param++);
833  const VArray<float> &randomness = get_randomness(param++);
834  MutableSpan<float> r_distance = get_r_distance(param++);
835  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
836  MutableSpan<float3> r_position = get_r_position(param++);
837  const bool calc_distance = !r_distance.is_empty();
838  const bool calc_color = !r_color.is_empty();
839  const bool calc_position = !r_position.is_empty();
840  for (int64_t i : mask) {
841  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
842  float3 col;
843  float2 pos;
844  noise::voronoi_f2(float2(vector[i].x, vector[i].y) * scale[i],
845  0.0f,
846  rand,
847  metric_,
848  calc_distance ? &r_distance[i] : nullptr,
849  calc_color ? &col : nullptr,
850  calc_position ? &pos : nullptr);
851  if (calc_color) {
852  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
853  }
854  if (calc_position) {
855  pos = math::safe_divide(pos, scale[i]);
856  r_position[i] = float3(pos.x, pos.y, 0.0f);
857  }
858  }
859  break;
860  }
861  case SHD_VORONOI_SMOOTH_F1: {
862  const VArray<float3> &vector = get_vector(param++);
863  const VArray<float> &scale = get_scale(param++);
864  const VArray<float> &smoothness = get_smoothness(param++);
865  const VArray<float> &randomness = get_randomness(param++);
866  MutableSpan<float> r_distance = get_r_distance(param++);
867  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
868  MutableSpan<float3> r_position = get_r_position(param++);
869  const bool calc_distance = !r_distance.is_empty();
870  const bool calc_color = !r_color.is_empty();
871  const bool calc_position = !r_position.is_empty();
872  for (int64_t i : mask) {
873  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
874  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
875  float3 col;
876  float2 pos;
877  noise::voronoi_smooth_f1(float2(vector[i].x, vector[i].y) * scale[i],
878  smth,
879  0.0f,
880  rand,
881  metric_,
882  calc_distance ? &r_distance[i] : nullptr,
883  calc_color ? &col : nullptr,
884  calc_position ? &pos : nullptr);
885  if (calc_color) {
886  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
887  }
888  if (calc_position) {
889  pos = math::safe_divide(pos, scale[i]);
890  r_position[i] = float3(pos.x, pos.y, 0.0f);
891  }
892  }
893  break;
894  }
895  }
896  break;
897  }
898  case 3: {
899  switch (feature_) {
900  case SHD_VORONOI_F1: {
901  const VArray<float3> &vector = get_vector(param++);
902  const VArray<float> &scale = get_scale(param++);
903  const VArray<float> &randomness = get_randomness(param++);
904  MutableSpan<float> r_distance = get_r_distance(param++);
905  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
906  MutableSpan<float3> r_position = get_r_position(param++);
907  const bool calc_distance = !r_distance.is_empty();
908  const bool calc_color = !r_color.is_empty();
909  const bool calc_position = !r_position.is_empty();
910  for (int64_t i : mask) {
911  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
912  float3 col;
913  noise::voronoi_f1(vector[i] * scale[i],
914  0.0f,
915  rand,
916  metric_,
917  calc_distance ? &r_distance[i] : nullptr,
918  calc_color ? &col : nullptr,
919  calc_position ? &r_position[i] : nullptr);
920  if (calc_color) {
921  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
922  }
923  if (calc_position) {
924  r_position[i] = math::safe_divide(r_position[i], scale[i]);
925  }
926  }
927  break;
928  }
929  case SHD_VORONOI_F2: {
930  const VArray<float3> &vector = get_vector(param++);
931  const VArray<float> &scale = get_scale(param++);
932  const VArray<float> &randomness = get_randomness(param++);
933  MutableSpan<float> r_distance = get_r_distance(param++);
934  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
935  MutableSpan<float3> r_position = get_r_position(param++);
936  const bool calc_distance = !r_distance.is_empty();
937  const bool calc_color = !r_color.is_empty();
938  const bool calc_position = !r_position.is_empty();
939  for (int64_t i : mask) {
940  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
941  float3 col;
942  noise::voronoi_f2(vector[i] * scale[i],
943  0.0f,
944  rand,
945  metric_,
946  calc_distance ? &r_distance[i] : nullptr,
947  calc_color ? &col : nullptr,
948  calc_position ? &r_position[i] : nullptr);
949  if (calc_color) {
950  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
951  }
952  if (calc_position) {
953  r_position[i] = math::safe_divide(r_position[i], scale[i]);
954  }
955  }
956  break;
957  }
958  case SHD_VORONOI_SMOOTH_F1: {
959  const VArray<float3> &vector = get_vector(param++);
960  const VArray<float> &scale = get_scale(param++);
961  const VArray<float> &smoothness = get_smoothness(param++);
962  const VArray<float> &randomness = get_randomness(param++);
963  MutableSpan<float> r_distance = get_r_distance(param++);
964  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
965  MutableSpan<float3> r_position = get_r_position(param++);
966  const bool calc_distance = !r_distance.is_empty();
967  const bool calc_color = !r_color.is_empty();
968  const bool calc_position = !r_position.is_empty();
969  {
970  for (int64_t i : mask) {
971  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
972  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
973  float3 col;
974  noise::voronoi_smooth_f1(vector[i] * scale[i],
975  smth,
976  0.0f,
977  rand,
978  metric_,
979  calc_distance ? &r_distance[i] : nullptr,
980  calc_color ? &col : nullptr,
981  calc_position ? &r_position[i] : nullptr);
982  if (calc_color) {
983  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
984  }
985  if (calc_position) {
986  r_position[i] = math::safe_divide(r_position[i], scale[i]);
987  }
988  }
989  }
990 
991  break;
992  }
993  }
994  break;
995  }
996  case 4: {
997  switch (feature_) {
998  case SHD_VORONOI_F1: {
999  const VArray<float3> &vector = get_vector(param++);
1000  const VArray<float> &w = get_w(param++);
1001  const VArray<float> &scale = get_scale(param++);
1002  const VArray<float> &randomness = get_randomness(param++);
1003  MutableSpan<float> r_distance = get_r_distance(param++);
1004  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
1005  MutableSpan<float3> r_position = get_r_position(param++);
1006  MutableSpan<float> r_w = get_r_w(param++);
1007  const bool calc_distance = !r_distance.is_empty();
1008  const bool calc_color = !r_color.is_empty();
1009  const bool calc_position = !r_position.is_empty();
1010  const bool calc_w = !r_w.is_empty();
1011  for (int64_t i : mask) {
1012  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1013  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
1014  float3 col;
1015  float4 pos;
1017  0.0f,
1018  rand,
1019  metric_,
1020  calc_distance ? &r_distance[i] : nullptr,
1021  calc_color ? &col : nullptr,
1022  calc_position || calc_w ? &pos : nullptr);
1023  if (calc_color) {
1024  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
1025  }
1026  if (calc_position || calc_w) {
1027  pos = math::safe_divide(pos, scale[i]);
1028  if (calc_position) {
1029  r_position[i] = float3(pos.x, pos.y, pos.z);
1030  }
1031  if (calc_w) {
1032  r_w[i] = pos.w;
1033  }
1034  }
1035  }
1036  break;
1037  }
1038  case SHD_VORONOI_F2: {
1039  const VArray<float3> &vector = get_vector(param++);
1040  const VArray<float> &w = get_w(param++);
1041  const VArray<float> &scale = get_scale(param++);
1042  const VArray<float> &randomness = get_randomness(param++);
1043  MutableSpan<float> r_distance = get_r_distance(param++);
1044  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
1045  MutableSpan<float3> r_position = get_r_position(param++);
1046  MutableSpan<float> r_w = get_r_w(param++);
1047  const bool calc_distance = !r_distance.is_empty();
1048  const bool calc_color = !r_color.is_empty();
1049  const bool calc_position = !r_position.is_empty();
1050  const bool calc_w = !r_w.is_empty();
1051  for (int64_t i : mask) {
1052  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1053  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
1054  float3 col;
1055  float4 pos;
1057  0.0f,
1058  rand,
1059  metric_,
1060  calc_distance ? &r_distance[i] : nullptr,
1061  calc_color ? &col : nullptr,
1062  calc_position || calc_w ? &pos : nullptr);
1063  if (calc_color) {
1064  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
1065  }
1066  if (calc_position || calc_w) {
1067  pos = math::safe_divide(pos, scale[i]);
1068  if (calc_position) {
1069  r_position[i] = float3(pos.x, pos.y, pos.z);
1070  }
1071  if (calc_w) {
1072  r_w[i] = pos.w;
1073  }
1074  }
1075  }
1076  break;
1077  }
1078  case SHD_VORONOI_SMOOTH_F1: {
1079  const VArray<float3> &vector = get_vector(param++);
1080  const VArray<float> &w = get_w(param++);
1081  const VArray<float> &scale = get_scale(param++);
1082  const VArray<float> &smoothness = get_smoothness(param++);
1083  const VArray<float> &randomness = get_randomness(param++);
1084  MutableSpan<float> r_distance = get_r_distance(param++);
1085  MutableSpan<ColorGeometry4f> r_color = get_r_color(param++);
1086  MutableSpan<float3> r_position = get_r_position(param++);
1087  MutableSpan<float> r_w = get_r_w(param++);
1088  const bool calc_distance = !r_distance.is_empty();
1089  const bool calc_color = !r_color.is_empty();
1090  const bool calc_position = !r_position.is_empty();
1091  const bool calc_w = !r_w.is_empty();
1092  for (int64_t i : mask) {
1093  const float smth = std::min(std::max(smoothness[i] / 2.0f, 0.0f), 0.5f);
1094  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1095  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
1096  float3 col;
1097  float4 pos;
1099  smth,
1100  0.0f,
1101  rand,
1102  metric_,
1103  calc_distance ? &r_distance[i] : nullptr,
1104  calc_color ? &col : nullptr,
1105  calc_position || calc_w ? &pos : nullptr);
1106  if (calc_color) {
1107  r_color[i] = ColorGeometry4f(col[0], col[1], col[2], 1.0f);
1108  }
1109  if (calc_position || calc_w) {
1110  pos = math::safe_divide(pos, scale[i]);
1111  if (calc_position) {
1112  r_position[i] = float3(pos.x, pos.y, pos.z);
1113  }
1114  if (calc_w) {
1115  r_w[i] = pos.w;
1116  }
1117  }
1118  }
1119  break;
1120  }
1121  }
1122  break;
1123  }
1124  }
1125  }
1126 
1128  {
1129  return voronoi_execution_hints;
1130  }
1131 };
1132 
1134  private:
1135  int dimensions_;
1136  int feature_;
1137 
1138  public:
1139  VoronoiEdgeFunction(int dimensions, int feature) : dimensions_(dimensions), feature_(feature)
1140  {
1141  BLI_assert(dimensions >= 1 && dimensions <= 4);
1142  BLI_assert(feature >= 3 && feature <= 4);
1143  static std::array<fn::MFSignature, 8> signatures{
1148 
1153  };
1154  this->set_signature(&signatures[dimensions + (feature - 3) * 4 - 1]);
1155  }
1156 
1157  static fn::MFSignature create_signature(int dimensions, int feature)
1158  {
1159  fn::MFSignatureBuilder signature{"voronoi_edge"};
1160 
1161  if (ELEM(dimensions, 2, 3, 4)) {
1162  signature.single_input<float3>("Vector");
1163  }
1164  if (ELEM(dimensions, 1, 4)) {
1165  signature.single_input<float>("W");
1166  }
1167  signature.single_input<float>("Scale");
1168  signature.single_input<float>("Randomness");
1169 
1170  if (feature == SHD_VORONOI_DISTANCE_TO_EDGE) {
1171  signature.single_output<float>("Distance");
1172  }
1173  if (feature == SHD_VORONOI_N_SPHERE_RADIUS) {
1174  signature.single_output<float>("Radius");
1175  }
1176 
1177  return signature.build();
1178  }
1179 
1181  {
1182  auto get_vector = [&](int param_index) -> VArray<float3> {
1183  return params.readonly_single_input<float3>(param_index, "Vector");
1184  };
1185  auto get_w = [&](int param_index) -> VArray<float> {
1186  return params.readonly_single_input<float>(param_index, "W");
1187  };
1188  auto get_scale = [&](int param_index) -> VArray<float> {
1189  return params.readonly_single_input<float>(param_index, "Scale");
1190  };
1191  auto get_randomness = [&](int param_index) -> VArray<float> {
1192  return params.readonly_single_input<float>(param_index, "Randomness");
1193  };
1194  auto get_r_distance = [&](int param_index) -> MutableSpan<float> {
1195  return params.uninitialized_single_output<float>(param_index, "Distance");
1196  };
1197  auto get_r_radius = [&](int param_index) -> MutableSpan<float> {
1198  return params.uninitialized_single_output<float>(param_index, "Radius");
1199  };
1200 
1201  int param = 0;
1202  switch (dimensions_) {
1203  case 1: {
1204  const VArray<float> &w = get_w(param++);
1205  const VArray<float> &scale = get_scale(param++);
1206  const VArray<float> &randomness = get_randomness(param++);
1207  switch (feature_) {
1209  MutableSpan<float> r_distance = get_r_distance(param++);
1210  for (int64_t i : mask) {
1211  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1212  const float p = w[i] * scale[i];
1213  noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
1214  }
1215  break;
1216  }
1218  MutableSpan<float> r_radius = get_r_radius(param++);
1219  for (int64_t i : mask) {
1220  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1221  const float p = w[i] * scale[i];
1222  noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
1223  }
1224  break;
1225  }
1226  }
1227  break;
1228  }
1229  case 2: {
1230  const VArray<float3> &vector = get_vector(param++);
1231  const VArray<float> &scale = get_scale(param++);
1232  const VArray<float> &randomness = get_randomness(param++);
1233  switch (feature_) {
1235  MutableSpan<float> r_distance = get_r_distance(param++);
1236  for (int64_t i : mask) {
1237  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1238  const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
1239  noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
1240  }
1241  break;
1242  }
1244  MutableSpan<float> r_radius = get_r_radius(param++);
1245  for (int64_t i : mask) {
1246  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1247  const float2 p = float2(vector[i].x, vector[i].y) * scale[i];
1248  noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
1249  }
1250  break;
1251  }
1252  }
1253  break;
1254  }
1255  case 3: {
1256  const VArray<float3> &vector = get_vector(param++);
1257  const VArray<float> &scale = get_scale(param++);
1258  const VArray<float> &randomness = get_randomness(param++);
1259  switch (feature_) {
1261  MutableSpan<float> r_distance = get_r_distance(param++);
1262  for (int64_t i : mask) {
1263  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1264  noise::voronoi_distance_to_edge(vector[i] * scale[i], rand, &r_distance[i]);
1265  }
1266  break;
1267  }
1269  MutableSpan<float> r_radius = get_r_radius(param++);
1270  for (int64_t i : mask) {
1271  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1272  noise::voronoi_n_sphere_radius(vector[i] * scale[i], rand, &r_radius[i]);
1273  }
1274  break;
1275  }
1276  }
1277  break;
1278  }
1279  case 4: {
1280  const VArray<float3> &vector = get_vector(param++);
1281  const VArray<float> &w = get_w(param++);
1282  const VArray<float> &scale = get_scale(param++);
1283  const VArray<float> &randomness = get_randomness(param++);
1284  switch (feature_) {
1286  MutableSpan<float> r_distance = get_r_distance(param++);
1287  for (int64_t i : mask) {
1288  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1289  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
1290  noise::voronoi_distance_to_edge(p, rand, &r_distance[i]);
1291  }
1292  break;
1293  }
1295  MutableSpan<float> r_radius = get_r_radius(param++);
1296  for (int64_t i : mask) {
1297  const float rand = std::min(std::max(randomness[i], 0.0f), 1.0f);
1298  const float4 p = float4(vector[i].x, vector[i].y, vector[i].z, w[i]) * scale[i];
1299  noise::voronoi_n_sphere_radius(p, rand, &r_radius[i]);
1300  }
1301  break;
1302  }
1303  }
1304  break;
1305  }
1306  }
1307  }
1308 
1310  {
1311  return voronoi_execution_hints;
1312  }
1313 };
1314 
1316 {
1317  const NodeTexVoronoi &storage = node_storage(builder.node());
1318  bool minowski =
1319  (storage.distance == SHD_VORONOI_MINKOWSKI && storage.dimensions != 1 &&
1321  bool dist_radius = ELEM(
1323  if (dist_radius) {
1325  storage.feature);
1326  }
1327  else if (minowski) {
1329  storage.feature);
1330  }
1331  else {
1333  storage.dimensions, storage.feature, storage.distance);
1334  }
1335 }
1336 
1337 } // namespace blender::nodes::node_shader_tex_voronoi_cc
1338 
1340 {
1341  namespace file_ns = blender::nodes::node_shader_tex_voronoi_cc;
1342 
1343  static bNodeType ntype;
1344 
1345  sh_fn_node_type_base(&ntype, SH_NODE_TEX_VORONOI, "Voronoi Texture", NODE_CLASS_TEXTURE);
1350  &ntype, "NodeTexVoronoi", node_free_standard_storage, node_copy_standard_storage);
1354 
1355  nodeRegisterType(&ntype);
1356 }
void node_type_gpu(struct bNodeType *ntype, NodeGPUExecFunction gpu_fn)
Definition: node.cc:4465
void node_type_update(struct bNodeType *ntype, void(*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4443
#define NODE_STORAGE_FUNCS(StorageT)
Definition: BKE_node.h:1563
void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available)
Definition: node.cc:3664
void node_type_init(struct bNodeType *ntype, void(*initfunc)(struct bNodeTree *ntree, struct bNode *node))
Definition: node.cc:4390
void node_type_storage(struct bNodeType *ntype, const char *storagename, void(*freefunc)(struct bNode *node), void(*copyfunc)(struct bNodeTree *dest_ntree, struct bNode *dest_node, const struct bNode *src_node))
Definition: node.cc:4426
struct bNodeSocket * nodeFindSocket(const struct bNode *node, eNodeSocketInOut in_out, const char *identifier)
#define NODE_CLASS_TEXTURE
Definition: BKE_node.h:355
void nodeRegisterType(struct bNodeType *ntype)
Definition: node.cc:1357
void BKE_texture_mapping_default(struct TexMapping *texmap, int type)
Definition: texture.c:238
void BKE_texture_colormapping_default(struct ColorMapping *colormap)
Definition: texture.c:340
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define UNUSED(x)
#define ELEM(...)
@ SHD_VORONOI_F2
@ SHD_VORONOI_SMOOTH_F1
@ SHD_VORONOI_DISTANCE_TO_EDGE
@ SHD_VORONOI_F1
@ SHD_VORONOI_N_SPHERE_RADIUS
@ SOCK_OUT
@ SOCK_IN
@ SHD_VORONOI_EUCLIDEAN
@ SHD_VORONOI_MINKOWSKI
#define TEXMAP_TYPE_POINT
_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 y
GPUNodeLink * GPU_constant(const float *num)
bool GPU_stack_link(GPUMaterial *mat, struct bNode *node, const char *name, GPUNodeStack *in, GPUNodeStack *out,...)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise SH_NODE_TEX_VORONOI
@ PROP_FACTOR
Definition: RNA_types.h:144
@ UI_ITEM_R_SPLIT_EMPTY_NAME
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
constexpr bool is_empty() const
Definition: BLI_span.hh:519
void set_signature(const MFSignature *signature)
const MFSignature & signature() const
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
static fn::MFSignature create_signature(int dimensions, int feature)
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
static fn::MFSignature create_signature(int dimensions, int feature)
static fn::MFSignature create_signature(int dimensions, int feature)
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
OperationNode * node
bNodeTree * ntree
uint pos
uint col
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
T safe_divide(const T &a, const T &b)
static void node_shader_init_tex_voronoi(bNodeTree *UNUSED(ntree), bNode *node)
static void sh_node_tex_voronoi_declare(NodeDeclarationBuilder &b)
static void sh_node_voronoi_build_multi_function(NodeMultiFunctionBuilder &builder)
static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node)
static MultiFunction::ExecutionHints voronoi_execution_hints
static int node_shader_gpu_tex_voronoi(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
static void node_shader_buts_tex_voronoi(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
static const char * gpu_shader_get_name(const int feature, const int dimensions)
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
void voronoi_distance_to_edge(float w, float randomness, float *r_distance)
Definition: noise.cc:1498
void voronoi_f1(float w, float randomness, float *r_distance, float3 *r_color, float *r_w)
Definition: noise.cc:1380
void voronoi_f2(float w, float randomness, float *r_distance, float3 *r_color, float *r_w)
Definition: noise.cc:1456
vec_base< float, 3 > float3
vec_base< float, 4 > float4
vec_base< float, 2 > float2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
Definition: BLI_color.hh:346
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
void register_node_type_sh_tex_voronoi()
void node_shader_gpu_tex_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *UNUSED(out))
void node_shader_gpu_default_tex_coord(GPUMaterial *mat, bNode *node, GPUNodeLink **link)
void sh_fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass)
void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node)
Definition: node_util.c:55
void node_free_standard_storage(bNode *node)
Definition: node_util.c:43
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
#define min(a, b)
Definition: sort.c:35
__int64 int64_t
Definition: stdint.h:89
Defines a node type.
Definition: BKE_node.h:226
void(* draw_buttons)(struct uiLayout *, struct bContext *C, struct PointerRNA *ptr)
Definition: BKE_node.h:244
NodeMultiFunctionBuildFunction build_multi_function
Definition: BKE_node.h:313
NodeDeclareFunction declare
Definition: BKE_node.h:324
float max
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480