[Bf-blender-cvs] [5b61737a8f4] master: Nodes: Add vector support to Map Range node

Charlie Jolly noreply at git.blender.org
Tue Dec 14 19:27:22 CET 2021


Commit: 5b61737a8f41688699fd1d711a25b7cea86d1530
Author: Charlie Jolly
Date:   Mon Dec 13 21:20:07 2021 +0000
Branches: master
https://developer.blender.org/rB5b61737a8f41688699fd1d711a25b7cea86d1530

Nodes: Add vector support to Map Range node

This replaces lost functionality from the old GN Attribute Map Range node.
This also adds vector support to the shader version of the node.

Notes:
This breaks forward compatibility as this node now uses data storage.

Reviewed By: HooglyBoogly, brecht

Differential Revision: https://developer.blender.org/D12760

===================================================================

M	intern/cycles/blender/shader.cpp
M	intern/cycles/kernel/osl/shaders/CMakeLists.txt
A	intern/cycles/kernel/osl/shaders/node_vector_map_range.osl
M	intern/cycles/kernel/svm/map_range.h
M	intern/cycles/kernel/svm/svm.h
M	intern/cycles/kernel/svm/types.h
M	intern/cycles/scene/shader_nodes.cpp
M	intern/cycles/scene/shader_nodes.h
M	source/blender/blenloader/intern/versioning_300.c
M	source/blender/editors/space_node/drawnode.cc
M	source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/shader/nodes/node_shader_map_range.cc

===================================================================

diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp
index 0f17834906d..70acfce6891 100644
--- a/intern/cycles/blender/shader.cpp
+++ b/intern/cycles/blender/shader.cpp
@@ -378,10 +378,19 @@ static ShaderNode *add_node(Scene *scene,
   }
   else if (b_node.is_a(&RNA_ShaderNodeMapRange)) {
     BL::ShaderNodeMapRange b_map_range_node(b_node);
-    MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
-    map_range_node->set_clamp(b_map_range_node.clamp());
-    map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
-    node = map_range_node;
+    if (b_map_range_node.data_type() == BL::ShaderNodeMapRange::data_type_FLOAT_VECTOR) {
+      VectorMapRangeNode *vector_map_range_node = graph->create_node<VectorMapRangeNode>();
+      vector_map_range_node->set_use_clamp(b_map_range_node.clamp());
+      vector_map_range_node->set_range_type(
+          (NodeMapRangeType)b_map_range_node.interpolation_type());
+      node = vector_map_range_node;
+    }
+    else {
+      MapRangeNode *map_range_node = graph->create_node<MapRangeNode>();
+      map_range_node->set_clamp(b_map_range_node.clamp());
+      map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type());
+      node = map_range_node;
+    }
   }
   else if (b_node.is_a(&RNA_ShaderNodeClamp)) {
     BL::ShaderNodeClamp b_clamp_node(b_node);
diff --git a/intern/cycles/kernel/osl/shaders/CMakeLists.txt b/intern/cycles/kernel/osl/shaders/CMakeLists.txt
index 6b62e7bb52f..4cafdb2a6d7 100644
--- a/intern/cycles/kernel/osl/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/shaders/CMakeLists.txt
@@ -92,6 +92,7 @@ set(SRC_OSL
   node_value.osl
   node_vector_curves.osl
   node_vector_math.osl
+  node_vector_map_range.osl
   node_vector_rotate.osl
   node_vector_transform.osl
   node_velvet_bsdf.osl
diff --git a/intern/cycles/kernel/osl/shaders/node_vector_map_range.osl b/intern/cycles/kernel/osl/shaders/node_vector_map_range.osl
new file mode 100644
index 00000000000..1a59691fc45
--- /dev/null
+++ b/intern/cycles/kernel/osl/shaders/node_vector_map_range.osl
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011-2021 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stdcycles.h"
+
+float safe_divide(float a, float b)
+{
+  return (b != 0.0) ? a / b : 0.0;
+}
+
+point safe_divide(point a, point b)
+{
+  return point(safe_divide(a.x, b.x), safe_divide(a.y, b.y), safe_divide(a.z, b.z));
+}
+
+shader node_vector_map_range(string range_type = "linear",
+                             int use_clamp = 0,
+                             point VectorIn = point(1.0, 1.0, 1.0),
+                             point From_Min_FLOAT3 = point(0.0, 0.0, 0.0),
+                             point From_Max_FLOAT3 = point(1.0, 1.0, 1.0),
+                             point To_Min_FLOAT3 = point(0.0, 0.0, 0.0),
+                             point To_Max_FLOAT3 = point(1.0, 1.0, 1.0),
+                             point Steps_FLOAT3 = point(4.0, 4.0, 4.0),
+                             output point VectorOut = point(0.0, 0.0, 0.0))
+{
+  point factor = VectorIn;
+  point from_min = From_Min_FLOAT3;
+  point from_max = From_Max_FLOAT3;
+  point to_min = To_Min_FLOAT3;
+  point to_max = To_Max_FLOAT3;
+  point steps = Steps_FLOAT3;
+
+  if (range_type == "stepped") {
+    factor = safe_divide((factor - from_min), (from_max - from_min));
+    factor = point((steps.x > 0.0) ? floor(factor.x * (steps.x + 1.0)) / steps.x : 0.0,
+                   (steps.y > 0.0) ? floor(factor.y * (steps.y + 1.0)) / steps.y : 0.0,
+                   (steps.z > 0.0) ? floor(factor.z * (steps.z + 1.0)) / steps.z : 0.0);
+  }
+  else if (range_type == "smoothstep") {
+    factor = safe_divide((factor - from_min), (from_max - from_min));
+    factor = clamp(factor, 0.0, 1.0);
+    factor = (3.0 - 2.0 * factor) * (factor * factor);
+  }
+  else if (range_type == "smootherstep") {
+    factor = safe_divide((factor - from_min), (from_max - from_min));
+    factor = clamp(factor, 0.0, 1.0);
+    factor = factor * factor * factor * (factor * (factor * 6.0 - 15.0) + 10.0);
+  }
+  else {
+    factor = safe_divide((factor - from_min), (from_max - from_min));
+  }
+  VectorOut = to_min + factor * (to_max - to_min);
+  if (use_clamp > 0) {
+    VectorOut.x = (to_min.x > to_max.x) ? clamp(VectorOut.x, to_max.x, to_min.x) :
+                                          clamp(VectorOut.x, to_min.x, to_max.x);
+    VectorOut.y = (to_min.y > to_max.y) ? clamp(VectorOut.y, to_max.y, to_min.y) :
+                                          clamp(VectorOut.y, to_min.y, to_max.y);
+    VectorOut.z = (to_min.z > to_max.z) ? clamp(VectorOut.z, to_max.z, to_min.z) :
+                                          clamp(VectorOut.z, to_min.z, to_max.z);
+  }
+}
diff --git a/intern/cycles/kernel/svm/map_range.h b/intern/cycles/kernel/svm/map_range.h
index fdbfc6531c4..bc5dcbd0238 100644
--- a/intern/cycles/kernel/svm/map_range.h
+++ b/intern/cycles/kernel/svm/map_range.h
@@ -88,4 +88,78 @@ ccl_device_noinline int svm_node_map_range(KernelGlobals kg,
   return offset;
 }
 
+ccl_device_noinline int svm_node_vector_map_range(KernelGlobals kg,
+                                                  ccl_private ShaderData *sd,
+                                                  ccl_private float *stack,
+                                                  uint value_stack_offset,
+                                                  uint parameters_stack_offsets,
+                                                  uint results_stack_offsets,
+                                                  int offset)
+{
+  uint from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset;
+  uint steps_stack_offset, clamp_stack_offset, range_type_stack_offset, result_stack_offset;
+  svm_unpack_node_uchar4(parameters_stack_offsets,
+                         &from_min_stack_offset,
+                         &from_max_stack_offset,
+                         &to_min_stack_offset,
+                         &to_max_stack_offset);
+  svm_unpack_node_uchar4(results_stack_offsets,
+                         &steps_stack_offset,
+                         &clamp_stack_offset,
+                         &range_type_stack_offset,
+                         &result_stack_offset);
+
+  float3 value = stack_load_float3(stack, value_stack_offset);
+  float3 from_min = stack_load_float3(stack, from_min_stack_offset);
+  float3 from_max = stack_load_float3(stack, from_max_stack_offset);
+  float3 to_min = stack_load_float3(stack, to_min_stack_offset);
+  float3 to_max = stack_load_float3(stack, to_max_stack_offset);
+  float3 steps = stack_load_float3(stack, steps_stack_offset);
+
+  int type = range_type_stack_offset;
+  int use_clamp = (type == NODE_MAP_RANGE_SMOOTHSTEP || type == NODE_MAP_RANGE_SMOOTHERSTEP) ?
+                      0 :
+                      clamp_stack_offset;
+  float3 result;
+  float3 factor = value;
+  switch (range_type_stack_offset) {
+    default:
+    case NODE_MAP_RANGE_LINEAR:
+      factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
+      break;
+    case NODE_MAP_RANGE_STEPPED: {
+      factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
+      factor = make_float3((steps.x > 0.0f) ? floorf(factor.x * (steps.x + 1.0f)) / steps.x : 0.0f,
+                           (steps.y > 0.0f) ? floorf(factor.y * (steps.y + 1.0f)) / steps.y : 0.0f,
+                           (steps.z > 0.0f) ? floorf(factor.z * (steps.z + 1.0f)) / steps.z :
+                                              0.0f);
+      break;
+    }
+    case NODE_MAP_RANGE_SMOOTHSTEP: {
+      factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
+      factor = clamp(factor, zero_float3(), one_float3());
+      factor = (make_float3(3.0f) - 2.0f * factor) * (factor * factor);
+      break;
+    }
+    case NODE_MAP_RANGE_SMOOTHERSTEP: {
+      factor = safe_divide_float3_float3((value - from_min), (from_max - from_min));
+      factor = clamp(factor, zero_float3(), one_float3());
+      factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f);
+      break;
+    }
+  }
+  result = to_min + factor * (to_max - to_min);
+  if (use_clamp > 0) {
+    result.x = (to_min.x > to_max.x) ? clamp(result.x, to_max.x, to_min.x) :
+                                       clamp(result.x, to_min.x, to_max.x);
+    result.y = (to_min.y > to_max.y) ? clamp(result.y, to_max.y, to_min.y) :
+                                       clamp(result.y, to_min.y, to_max.y);
+    result.z = (to_min.z > to_max.z) ? clamp(result.z, to_max.z, to_min.z) :
+                                       clamp(result.z, to_min.z, to_max.z);
+  }
+
+  stack_store_float3(stack, result_stack_offset, result);
+  return offset;
+}
+
 CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index ce32e1a520f..b226bc66771 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -562,6 +562,9 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
       case NODE_MAP_RANGE:
         offset = svm_node_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
         break;
+      case NODE_VECTOR_MAP_RANGE:
+        offset = svm_node_vector_map_range(kg, sd, stack, node.y, node.z, node.w, offset);
+        break;
       case NODE_CLAMP:
         offset = svm_node_clamp(kg, sd, stack, node.y, node.z, node.w, offset);
         break;
diff --git a/intern/cycles/kernel/svm/types.h b/intern/cycles/kernel/svm/types.h
index 8c95c571815..384549b7f09 100644
--- a/intern/cycles/kernel/svm/

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list