Cycles: Optimize vector math node without links to single values.
authorThomas Dinges <blender@dingto.org>
Wed, 24 Dec 2014 21:45:08 +0000 (22:45 +0100)
committerThomas Dinges <blender@dingto.org>
Wed, 24 Dec 2014 21:45:08 +0000 (22:45 +0100)
intern/cycles/kernel/svm/svm_math.h
intern/cycles/kernel/svm/svm_math_util.h
intern/cycles/render/nodes.cpp

index e3d8c1f..de703d3 100644 (file)
 
 CCL_NAMESPACE_BEGIN
 
-ccl_device float average_fac(float3 v)
-{
-       return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
-}
-
-ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
-{
-       if(type == NODE_VECTOR_MATH_ADD) {
-               *Vector = Vector1 + Vector2;
-               *Fac = average_fac(*Vector);
-       }
-       else if(type == NODE_VECTOR_MATH_SUBTRACT) {
-               *Vector = Vector1 - Vector2;
-               *Fac = average_fac(*Vector);
-       }
-       else if(type == NODE_VECTOR_MATH_AVERAGE) {
-               *Fac = len(Vector1 + Vector2);
-               *Vector = normalize(Vector1 + Vector2);
-       }
-       else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) {
-               *Fac = dot(Vector1, Vector2);
-               *Vector = make_float3(0.0f, 0.0f, 0.0f);
-       }
-       else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
-               float3 c = cross(Vector1, Vector2);
-               *Fac = len(c);
-               *Vector = normalize(c);
-       }
-       else if(type == NODE_VECTOR_MATH_NORMALIZE) {
-               *Fac = len(Vector1);
-               *Vector = normalize(Vector1);
-       }
-       else {
-               *Fac = 0.0f;
-               *Vector = make_float3(0.0f, 0.0f, 0.0f);
-       }
-}
-
 /* Nodes */
 
 ccl_device void svm_node_math(KernelGlobals *kg, ShaderData *sd, float *stack, uint itype, uint f1_offset, uint f2_offset, int *offset)
index b813bf5..01408c3 100644 (file)
 
 CCL_NAMESPACE_BEGIN
 
+ccl_device float average_fac(float3 v)
+{
+       return (fabsf(v.x) + fabsf(v.y) + fabsf(v.z))/3.0f;
+}
+
+ccl_device void svm_vector_math(float *Fac, float3 *Vector, NodeVectorMath type, float3 Vector1, float3 Vector2)
+{
+       if(type == NODE_VECTOR_MATH_ADD) {
+               *Vector = Vector1 + Vector2;
+               *Fac = average_fac(*Vector);
+       }
+       else if(type == NODE_VECTOR_MATH_SUBTRACT) {
+               *Vector = Vector1 - Vector2;
+               *Fac = average_fac(*Vector);
+       }
+       else if(type == NODE_VECTOR_MATH_AVERAGE) {
+               *Fac = len(Vector1 + Vector2);
+               *Vector = normalize(Vector1 + Vector2);
+       }
+       else if(type == NODE_VECTOR_MATH_DOT_PRODUCT) {
+               *Fac = dot(Vector1, Vector2);
+               *Vector = make_float3(0.0f, 0.0f, 0.0f);
+       }
+       else if(type == NODE_VECTOR_MATH_CROSS_PRODUCT) {
+               float3 c = cross(Vector1, Vector2);
+               *Fac = len(c);
+               *Vector = normalize(c);
+       }
+       else if(type == NODE_VECTOR_MATH_NORMALIZE) {
+               *Fac = len(Vector1);
+               *Vector = normalize(Vector1);
+       }
+       else {
+               *Fac = 0.0f;
+               *Vector = make_float3(0.0f, 0.0f, 0.0f);
+       }
+}
+
 ccl_device float svm_math(NodeMath type, float Fac1, float Fac2)
 {
        float Fac;
index 62bdf7c..41fa8fd 100644 (file)
@@ -3754,11 +3754,31 @@ void VectorMathNode::compile(SVMCompiler& compiler)
        ShaderOutput *value_out = output("Value");
        ShaderOutput *vector_out = output("Vector");
 
-       compiler.stack_assign(vector1_in);
-       compiler.stack_assign(vector2_in);
        compiler.stack_assign(value_out);
        compiler.stack_assign(vector_out);
 
+       /* Optimize vector math node without links to a single value node. */
+       if(vector1_in->link == NULL && vector2_in->link == NULL) {
+               float optimized_value;
+               float3 optimized_vector;
+               svm_vector_math(&optimized_value,
+                               &optimized_vector,
+                               (NodeVectorMath)type_enum[type],
+                               vector1_in->value,
+                               vector2_in->value);
+
+               compiler.add_node(NODE_VALUE_F,
+                                 __float_as_int(optimized_value),
+                                 value_out->stack_offset);
+
+               compiler.add_node(NODE_VALUE_V, vector_out->stack_offset);
+               compiler.add_node(NODE_VALUE_V, optimized_vector);
+               return;
+       }
+
+       compiler.stack_assign(vector1_in);
+       compiler.stack_assign(vector2_in);
+
        compiler.add_node(NODE_VECTOR_MATH, type_enum[type], vector1_in->stack_offset, vector2_in->stack_offset);
        compiler.add_node(NODE_VECTOR_MATH, value_out->stack_offset, vector_out->stack_offset);
 }