Cycles: Refactor of constant fold.
* Move constant folding from nodes to the shader graph. This way it's part of our (later) 4-step optimization process. * Instead of only doing a one level constant fold, we can now do a recursive constant fold, allowing us to simplify shaders much further. Constant folding is implemented for Blackbody, Math and VectorMath nodes. Example (the highlighted nodes are removed before rendering): Before: http://archive.dingto.org/2015/blender/code/one_level_constant_fold.jpg Now: http://archive.dingto.org/2015/blender/code/multi_level_constant_fold.jpg Thanks to Sergey and Brecht for Review! Differential Revision: https://developer.blender.org/D1626
This commit is contained in:
@@ -297,7 +297,7 @@ void ShaderGraph::finalize(Scene *scene,
|
||||
finalized = true;
|
||||
}
|
||||
else if(do_simplify) {
|
||||
simplify_nodes(scene);
|
||||
simplify_settings(scene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,11 +562,44 @@ void ShaderGraph::remove_unneeded_nodes()
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2: Constant folding.
|
||||
* Try to constant fold some nodes, and pipe result directly to
|
||||
* the input socket of connected nodes.
|
||||
*/
|
||||
void ShaderGraph::constant_fold(set<ShaderNode*>& done, ShaderNode *node)
|
||||
{
|
||||
/* Only fold each node once. */
|
||||
if(done.find(node) != done.end())
|
||||
return;
|
||||
|
||||
done.insert(node);
|
||||
|
||||
/* Fold nodes connected to inputs first. */
|
||||
foreach(ShaderInput *in, node->inputs) {
|
||||
if(in->link) {
|
||||
constant_fold(done, in->link->parent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Then fold self. */
|
||||
foreach(ShaderOutput *sock, node->outputs) {
|
||||
float3 optimized_value = make_float3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if(node->constant_fold(sock, &optimized_value)) {
|
||||
/* Apply optimized value to connected sockets */
|
||||
foreach(ShaderInput *in, sock->links) {
|
||||
in->value = optimized_value;
|
||||
disconnect(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 3: Simplification.*/
|
||||
void ShaderGraph::simplify_nodes(Scene *scene)
|
||||
void ShaderGraph::simplify_settings(Scene *scene)
|
||||
{
|
||||
foreach(ShaderNode *node, nodes) {
|
||||
node->optimize(scene);
|
||||
node->simplify_settings(scene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -607,10 +640,11 @@ void ShaderGraph::clean(Scene *scene)
|
||||
remove_unneeded_nodes();
|
||||
|
||||
/* 2: Constant folding. */
|
||||
/* TODO(dingto): Implement */
|
||||
set<ShaderNode*> done;
|
||||
constant_fold(done, output());
|
||||
|
||||
/* 3: Simplification. */
|
||||
simplify_nodes(scene);
|
||||
simplify_settings(scene);
|
||||
|
||||
/* 4: De-duplication. */
|
||||
/* TODO(dingto): Implement */
|
||||
|
Reference in New Issue
Block a user