Cycles: Implement constant fold for the ConvertNode.

This way socket type conversions (such as color to float, or float to vector) do not stop the folding process.
Example: http://www.pasteall.org/pic/show.php?id=96803 (selected nodes are folded).
This commit is contained in:
Thomas Dinges 2015-12-23 21:41:59 +01:00
parent 1a2b5d9a8b
commit 059b7a81e2
2 changed files with 52 additions and 0 deletions

@ -1621,6 +1621,56 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_, bool auto
assert(0);
}
bool ConvertNode::constant_fold(ShaderOutput *socket, float3 *optimized_value)
{
ShaderInput *in = inputs[0];
float3 value = in->value;
/* TODO(DingTo): conversion from/to int is not supported yet, don't fold in that case */
if(socket == outputs[0] && in->link == NULL) {
if(from == SHADER_SOCKET_FLOAT) {
if(to == SHADER_SOCKET_INT)
/* float to int */
return false;
else
/* float to float3 */
*optimized_value = make_float3(value.x, value.x, value.x);
}
else if(from == SHADER_SOCKET_INT) {
if(to == SHADER_SOCKET_FLOAT)
/* int to float */
return false;
else
/* int to vector/point/normal */
return false;
}
else if(to == SHADER_SOCKET_FLOAT) {
if(from == SHADER_SOCKET_COLOR)
/* color to float */
optimized_value->x = linear_rgb_to_gray(value);
else
/* vector/point/normal to float */
optimized_value->x = average(value);
}
else if(to == SHADER_SOCKET_INT) {
if(from == SHADER_SOCKET_COLOR)
/* color to int */
return false;
else
/* vector/point/normal to int */
return false;
}
else {
*optimized_value = value;
}
return true;
}
return false;
}
void ConvertNode::compile(SVMCompiler& compiler)
{
ShaderInput *in = inputs[0];

@ -252,6 +252,8 @@ public:
ConvertNode(ShaderSocketType from, ShaderSocketType to, bool autoconvert = false);
SHADER_NODE_BASE_CLASS(ConvertNode)
bool constant_fold(ShaderOutput *socket, float3 *optimized_value);
ShaderSocketType from, to;
};