Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht@blender.org>2020-12-22 02:50:22 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-12-22 16:25:50 +0300
commitdad5aded0cf6f69e15954b47a6e2f1d2e791d073 (patch)
treea76d8652870449498eb57996a93905390a4c9d18 /intern
parent2601501fce554290d9245fdbcb536c7c87c73f11 (diff)
Fix T84006: Cycles AOV not written with some mix shader node set ups
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/render/svm.cpp80
-rw-r--r--intern/cycles/render/svm.h6
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);