diff options
author | Brecht Van Lommel <brecht@blender.org> | 2020-12-22 02:50:22 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2020-12-22 16:25:50 +0300 |
commit | dad5aded0cf6f69e15954b47a6e2f1d2e791d073 (patch) | |
tree | a76d8652870449498eb57996a93905390a4c9d18 /intern/cycles | |
parent | 2601501fce554290d9245fdbcb536c7c87c73f11 (diff) |
Fix T84006: Cycles AOV not written with some mix shader node set ups
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/render/svm.cpp | 80 | ||||
-rw-r--r-- | intern/cycles/render/svm.h | 6 |
2 files changed, 51 insertions, 35 deletions
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index b2bc17aec19..6f5a03124f2 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -548,22 +548,23 @@ void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node, } } -void SVMCompiler::generate_aov_node(ShaderNode *node, CompilerState *state) +void SVMCompiler::find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes, + ShaderGraph *graph, + CompilerState *state) { - /* execute dependencies for node */ - foreach (ShaderInput *in, node->inputs) { - if (in->link != NULL) { - ShaderNodeSet dependencies; - find_dependencies(dependencies, state->nodes_done, in); - generate_svm_nodes(dependencies, state); + foreach (ShaderNode *node, graph->nodes) { + if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) { + OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node); + if (aov_node->slot >= 0) { + aov_nodes.insert(aov_node); + foreach (ShaderInput *in, node->inputs) { + if (in->link != NULL) { + find_dependencies(aov_nodes, state->nodes_done, in); + } + } + } } } - - /* compile node itself */ - generate_node(node, state->nodes_done); - - state->nodes_done.insert(node); - state->nodes_done_flag[node->id] = true; } void SVMCompiler::generate_multi_closure(ShaderNode *root_node, @@ -631,6 +632,25 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node, } } + /* For dependencies AOV nodes, prevent them from being categorized + * as exclusive deps of one or the other closure, since the need to + * execute them for AOV writing is not dependent on the closure + * weights. */ + if (state->aov_nodes.size()) { + set_intersection(state->aov_nodes.begin(), + state->aov_nodes.end(), + cl1deps.begin(), + cl1deps.end(), + std::inserter(shareddeps, shareddeps.begin()), + node_id_comp); + set_intersection(state->aov_nodes.begin(), + state->aov_nodes.end(), + cl2deps.begin(), + cl2deps.end(), + std::inserter(shareddeps, shareddeps.begin()), + node_id_comp); + } + if (!shareddeps.empty()) { if (cl1in->link) { generated_shared_closure_nodes(root_node, cl1in->link->parent, state, shareddeps); @@ -782,6 +802,9 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty } if (generate) { + if (type == SHADER_TYPE_SURFACE) { + find_aov_nodes_and_dependencies(state.aov_nodes, graph, &state); + } generate_multi_closure(clin->link->parent, clin->link->parent, &state); } } @@ -789,28 +812,15 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty /* compile output node */ output->compile(*this); - if (type == SHADER_TYPE_SURFACE) { - vector<OutputAOVNode *> aov_outputs; - foreach (ShaderNode *node, graph->nodes) { - if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) { - OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node); - if (aov_node->slot >= 0) { - aov_outputs.push_back(aov_node); - } - } - } - if (aov_outputs.size() > 0) { - /* AOV passes are only written if the object is directly visible, so - * there is no point in evaluating all the nodes generated only for the - * AOV outputs if that's not the case. Therefore, we insert - * NODE_AOV_START into the shader before the AOV-only nodes are - * generated which tells the kernel that it can stop evaluation - * early if AOVs will not be written. */ - add_node(NODE_AOV_START, 0, 0, 0); - foreach (OutputAOVNode *node, aov_outputs) { - generate_aov_node(node, &state); - } - } + if (!state.aov_nodes.empty()) { + /* AOV passes are only written if the object is directly visible, so + * there is no point in evaluating all the nodes generated only for the + * AOV outputs if that's not the case. Therefore, we insert + * NODE_AOV_START into the shader before the AOV-only nodes are + * generated which tells the kernel that it can stop evaluation + * early if AOVs will not be written. */ + add_node(NODE_AOV_START, 0, 0, 0); + generate_svm_nodes(state.aov_nodes, &state); } } diff --git a/intern/cycles/render/svm.h b/intern/cycles/render/svm.h index dd557de52d6..a4ca68e1d8d 100644 --- a/intern/cycles/render/svm.h +++ b/intern/cycles/render/svm.h @@ -176,6 +176,9 @@ class SVMCompiler { /* Set of closures which were already compiled. */ ShaderNodeSet closure_done; + /* Set of nodes used for writing AOVs. */ + ShaderNodeSet aov_nodes; + /* ** SVM nodes generation state ** */ /* Flag whether the node with corresponding ID was already compiled or @@ -197,6 +200,9 @@ class SVMCompiler { const ShaderNodeSet &done, ShaderInput *input, ShaderNode *skip_node = NULL); + void find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes, + ShaderGraph *graph, + CompilerState *state); void generate_node(ShaderNode *node, ShaderNodeSet &done); void generate_aov_node(ShaderNode *node, CompilerState *state); void generate_closure_node(ShaderNode *node, CompilerState *state); |