clamp for Mix node
authorDalai Felinto <dfelinto@gmail.com>
Thu, 30 Aug 2012 06:31:02 +0000 (06:31 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Thu, 30 Aug 2012 06:31:02 +0000 (06:31 +0000)
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
intern/cycles/blender/blender_shader.cpp
intern/cycles/kernel/osl/nodes/node_mix.osl
intern/cycles/kernel/svm/svm_mix.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
intern/cycles/render/nodes.h

index 5ec5cb929d6d50b9a55ecbb28e5080752a3aa28f..5569df927fb624e245400556f59b112cfe976b6d 100644 (file)
@@ -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")) {
index 37ab1ddac26bc14bd33e8e06f3ff7919d76da698..b82fee5edf0dfae082eb901792258e04db7ff45c 100644 (file)
@@ -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;
                }
index 8a462c995d369b15cd640630e7ad2029bcec66ef..9ba58e2b56ec726e51a35e78127ee0c1373be3a7 100644 (file)
@@ -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);
 }
 
index 6b455e713c287c0a8b2ed0373104265d2ddae9b0..888e4d9645e82b633e1349dc248c06c899205ae1 100644 (file)
@@ -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);
index df06b883cae4cb98d7cad1bb5682f3f8bc5047b0..38232eb9c04c51c11b1fc06143c66603fb484582 100644 (file)
@@ -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 {
index 07310cb4461d8b592fa6fac8d1c715f960bb71ce..b35fe151bac09e715cc0544ca414535e6de9a196 100644 (file)
@@ -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");
 }
 
index 2e0acc32e517b81518b43bf91206da4fbc65e870..650d6092f29d13ba39c7f72019e940cc48c3b760 100644 (file)
@@ -329,6 +329,8 @@ class MixNode : public ShaderNode {
 public:
        SHADER_NODE_CLASS(MixNode)
 
+       bool use_clamp;
+
        ustring type;
        static ShaderEnum type_enum;
 };