From e796581655ed9a36c263a20e7ed97856fc0f1070 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 25 Nov 2015 13:52:39 +0100 Subject: 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 --- intern/cycles/render/graph.cpp | 44 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'intern/cycles/render/graph.cpp') diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index e888cb37137..8468690841d 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -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& 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 done; + constant_fold(done, output()); /* 3: Simplification. */ - simplify_nodes(scene); + simplify_settings(scene); /* 4: De-duplication. */ /* TODO(dingto): Implement */ -- cgit v1.2.3