Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/blender/shader.cpp17
-rw-r--r--intern/cycles/kernel/osl/shaders/CMakeLists.txt1
-rw-r--r--intern/cycles/kernel/osl/shaders/node_vector_map_range.osl74
-rw-r--r--intern/cycles/kernel/svm/map_range.h74
-rw-r--r--intern/cycles/kernel/svm/svm.h3
-rw-r--r--intern/cycles/kernel/svm/types.h1
-rw-r--r--intern/cycles/scene/shader_nodes.cpp67
-rw-r--r--intern/cycles/scene/shader_nodes.h15
8 files changed, 248 insertions, 4 deletions
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/types.h
+++ b/intern/cycles/kernel/svm/types.h
@@ -114,6 +114,7 @@ typedef enum ShaderNodeType {
NODE_WAVELENGTH,
NODE_BLACKBODY,
NODE_MAP_RANGE,
+ NODE_VECTOR_MAP_RANGE,
NODE_CLAMP,
NODE_BEVEL,
NODE_AMBIENT_OCCLUSION,
diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp
index 0ffeddc9f13..c345d5bbc9a 100644
--- a/intern/cycles/scene/shader_nodes.cpp
+++ b/intern/cycles/scene/shader_nodes.cpp
@@ -5871,6 +5871,73 @@ void MapRangeNode::compile(OSLCompiler &compiler)
compiler.add(this, "node_map_range");
}
+/* Vector Map Range Node */
+
+NODE_DEFINE(VectorMapRangeNode)
+{
+ NodeType *type = NodeType::add("vector_map_range", create, NodeType::SHADER);
+
+ static NodeEnum type_enum;
+ type_enum.insert("linear", NODE_MAP_RANGE_LINEAR);
+ type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED);
+ type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP);
+ type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP);
+ SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR);
+
+ SOCKET_IN_VECTOR(vector, "Vector", zero_float3());
+ SOCKET_IN_VECTOR(from_min, "From_Min_FLOAT3", zero_float3());
+ SOCKET_IN_VECTOR(from_max, "From_Max_FLOAT3", one_float3());
+ SOCKET_IN_VECTOR(to_min, "To_Min_FLOAT3", zero_float3());
+ SOCKET_IN_VECTOR(to_max, "To_Max_FLOAT3", one_float3());
+ SOCKET_IN_VECTOR(steps, "Steps_FLOAT3", make_float3(4.0f));
+ SOCKET_BOOLEAN(use_clamp, "Use Clamp", false);
+
+ SOCKET_OUT_VECTOR(vector, "Vector");
+
+ return type;
+}
+
+VectorMapRangeNode::VectorMapRangeNode() : ShaderNode(get_node_type())
+{
+}
+
+void VectorMapRangeNode::expand(ShaderGraph *graph)
+{
+}
+
+void VectorMapRangeNode::compile(SVMCompiler &compiler)
+{
+ ShaderInput *vector_in = input("Vector");
+ ShaderInput *from_min_in = input("From_Min_FLOAT3");
+ ShaderInput *from_max_in = input("From_Max_FLOAT3");
+ ShaderInput *to_min_in = input("To_Min_FLOAT3");
+ ShaderInput *to_max_in = input("To_Max_FLOAT3");
+ ShaderInput *steps_in = input("Steps_FLOAT3");
+ ShaderOutput *vector_out = output("Vector");
+
+ int value_stack_offset = compiler.stack_assign(vector_in);
+ int from_min_stack_offset = compiler.stack_assign(from_min_in);
+ int from_max_stack_offset = compiler.stack_assign(from_max_in);
+ int to_min_stack_offset = compiler.stack_assign(to_min_in);
+ int to_max_stack_offset = compiler.stack_assign(to_max_in);
+ int steps_stack_offset = compiler.stack_assign(steps_in);
+ int result_stack_offset = compiler.stack_assign(vector_out);
+
+ compiler.add_node(
+ NODE_VECTOR_MAP_RANGE,
+ value_stack_offset,
+ compiler.encode_uchar4(
+ from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset),
+ compiler.encode_uchar4(steps_stack_offset, use_clamp, range_type, result_stack_offset));
+}
+
+void VectorMapRangeNode::compile(OSLCompiler &compiler)
+{
+ compiler.parameter(this, "range_type");
+ compiler.parameter(this, "use_clamp");
+ compiler.add(this, "node_vector_map_range");
+}
+
/* Clamp Node */
NODE_DEFINE(ClampNode)
diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h
index 64a2b1c7843..0faefd3041f 100644
--- a/intern/cycles/scene/shader_nodes.h
+++ b/intern/cycles/scene/shader_nodes.h
@@ -1263,6 +1263,21 @@ class BlackbodyNode : public ShaderNode {
NODE_SOCKET_API(float, temperature)
};
+class VectorMapRangeNode : public ShaderNode {
+ public:
+ SHADER_NODE_CLASS(VectorMapRangeNode)
+ void expand(ShaderGraph *graph);
+
+ NODE_SOCKET_API(float3, vector)
+ NODE_SOCKET_API(float3, from_min)
+ NODE_SOCKET_API(float3, from_max)
+ NODE_SOCKET_API(float3, to_min)
+ NODE_SOCKET_API(float3, to_max)
+ NODE_SOCKET_API(float3, steps)
+ NODE_SOCKET_API(NodeMapRangeType, range_type)
+ NODE_SOCKET_API(bool, use_clamp)
+};
+
class MapRangeNode : public ShaderNode {
public:
SHADER_NODE_CLASS(MapRangeNode)