From ded5e9cd2324eaa28b85d17d0f8d394f72625c8a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Thu, 30 Aug 2012 06:31:02 +0000 Subject: [PATCH] clamp for Mix node the implementation was following my early commit for Math node I haven't had a chance to run those through Brecht, but would like to do eventually. (they work fine though) --- intern/cycles/app/cycles_xml.cpp | 2 ++ intern/cycles/blender/blender_shader.cpp | 1 + intern/cycles/kernel/osl/nodes/node_mix.osl | 15 +++++++++++++++ intern/cycles/kernel/svm/svm_mix.h | 12 ++++++++++++ intern/cycles/kernel/svm/svm_types.h | 3 ++- intern/cycles/render/nodes.cpp | 8 ++++++++ intern/cycles/render/nodes.h | 2 ++ 7 files changed, 42 insertions(+), 1 deletion(-) diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp index 5ec5cb929d6..5569df927fb 100644 --- a/intern/cycles/app/cycles_xml.cpp +++ b/intern/cycles/app/cycles_xml.cpp @@ -484,6 +484,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug else if(string_iequals(node.name(), "mix")) { MixNode *mix = new MixNode(); xml_read_enum(&mix->type, MixNode::type_enum, node, "type"); + xml_read_bool(&mix->use_clamp, node, "use_clamp"); snode = mix; } else if(string_iequals(node.name(), "gamma")) { @@ -515,6 +516,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug else if(string_iequals(node.name(), "math")) { MathNode *math = new MathNode(); xml_read_enum(&math->type, MathNode::type_enum, node, "type"); + xml_read_bool(&math->use_clamp, node, "use_clamp"); snode = math; } else if(string_iequals(node.name(), "vector_math")) { diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 37ab1ddac26..b82fee5edf0 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -221,6 +221,7 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = new MixNode(); mix->type = MixNode::type_enum[b_mix_node.blend_type()]; + mix->use_clamp = b_mix_node.use_clamp(); node = mix; break; } diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/osl/nodes/node_mix.osl index 8a462c995d3..9ba58e2b56e 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix.osl +++ b/intern/cycles/kernel/osl/nodes/node_mix.osl @@ -267,8 +267,20 @@ color node_mix_linear(float t, color col1, color col2) return outcol; } +color node_mix_clamp(color col) +{ + color outcol = col; + + outcol[0] = clamp(col[0], 0.0, 1.0); + outcol[1] = clamp(col[2], 0.0, 1.0); + outcol[2] = clamp(col[2], 0.0, 1.0); + + return outcol; +} + shader node_mix( string type = "Mix", + int Clamp = false, float Fac = 0.5, color Color1 = color(0.0, 0.0, 0.0), color Color2 = color(0.0, 0.0, 0.0), @@ -312,5 +324,8 @@ shader node_mix( Color = node_mix_soft(t, Color1, Color2); if(type == "Linear Light") Color = node_mix_linear(t, Color1, Color2); + + if(Clamp) + Color = node_mix_clamp(Color); } diff --git a/intern/cycles/kernel/svm/svm_mix.h b/intern/cycles/kernel/svm/svm_mix.h index 6b455e713c2..888e4d9645e 100644 --- a/intern/cycles/kernel/svm/svm_mix.h +++ b/intern/cycles/kernel/svm/svm_mix.h @@ -276,6 +276,17 @@ __device float3 svm_mix_linear(float t, float3 col1, float3 col2) return outcol; } +__device float3 svm_mix_clamp(float3 col) +{ + float3 outcol = col; + + outcol.x = clamp(col.x, 0.0f, 1.0f); + outcol.y = clamp(col.y, 0.0f, 1.0f); + outcol.z = clamp(col.z, 0.0f, 1.0f); + + return outcol; +} + __device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) { float t = clamp(fac, 0.0f, 1.0f); @@ -299,6 +310,7 @@ __device float3 svm_mix(NodeMix type, float fac, float3 c1, float3 c2) case NODE_MIX_COLOR: return svm_mix_color(t, c1, c2); case NODE_MIX_SOFT: return svm_mix_soft(t, c1, c2); case NODE_MIX_LINEAR: return svm_mix_linear(t, c1, c2); + case NODE_MIX_CLAMP: return svm_mix_clamp(c1); } return make_float3(0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index df06b883cae..38232eb9c04 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -163,7 +163,8 @@ typedef enum NodeMix { NODE_MIX_VAL, NODE_MIX_COLOR, NODE_MIX_SOFT, - NODE_MIX_LINEAR + NODE_MIX_LINEAR, + NODE_MIX_CLAMP /* used for the clamp UI option */ } NodeMix; typedef enum NodeMath { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 07310cb4461..b35fe151bac 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -1971,6 +1971,8 @@ MixNode::MixNode() { type = ustring("Mix"); + use_clamp = false; + add_input("Fac", SHADER_SOCKET_FLOAT, 0.5f); add_input("Color1", SHADER_SOCKET_COLOR); add_input("Color2", SHADER_SOCKET_COLOR); @@ -2019,11 +2021,17 @@ void MixNode::compile(SVMCompiler& compiler) compiler.add_node(NODE_MIX, fac_in->stack_offset, color1_in->stack_offset, color2_in->stack_offset); compiler.add_node(NODE_MIX, type_enum[type], color_out->stack_offset); + + if(use_clamp) { + compiler.add_node(NODE_MIX, 0, color_out->stack_offset); + compiler.add_node(NODE_MIX, NODE_MIX_CLAMP, color_out->stack_offset); + } } void MixNode::compile(OSLCompiler& compiler) { compiler.parameter("type", type); + compiler.parameter("Clamp", use_clamp); compiler.add(this, "node_mix"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 2e0acc32e51..650d6092f29 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -329,6 +329,8 @@ class MixNode : public ShaderNode { public: SHADER_NODE_CLASS(MixNode) + bool use_clamp; + ustring type; static ShaderEnum type_enum; };