Cycles: Optimize vector math node without links to single values.

This commit is contained in:
Thomas Dinges 2014-12-24 22:45:08 +01:00
parent 76b4fad6db
commit 43421e9c53
3 changed files with 60 additions and 40 deletions

View File

@ -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)

View File

@ -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;

View 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);
}