From 43421e9c5354b6f061cd51922e1a31579b94c6af Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 24 Dec 2014 22:45:08 +0100 Subject: [PATCH] Cycles: Optimize vector math node without links to single values. --- intern/cycles/kernel/svm/svm_math.h | 38 ------------------------ intern/cycles/kernel/svm/svm_math_util.h | 38 ++++++++++++++++++++++++ intern/cycles/render/nodes.cpp | 24 +++++++++++++-- 3 files changed, 60 insertions(+), 40 deletions(-) diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index e3d8c1f3242..de703d3fd6e 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -16,44 +16,6 @@ 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) diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index b813bf531dc..01408c3ec49 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -16,6 +16,44 @@ 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; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 62bdf7cd162..41fa8fd5db2 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -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); }