[Bf-blender-cvs] [dad5aded0cf] master: Fix T84006: Cycles AOV not written with some mix shader node set ups

Brecht Van Lommel noreply at git.blender.org
Tue Dec 22 14:25:55 CET 2020


Commit: dad5aded0cf6f69e15954b47a6e2f1d2e791d073
Author: Brecht Van Lommel
Date:   Tue Dec 22 00:50:22 2020 +0100
Branches: master
https://developer.blender.org/rBdad5aded0cf6f69e15954b47a6e2f1d2e791d073

Fix T84006: Cycles AOV not written with some mix shader node set ups

===================================================================

M	intern/cycles/render/svm.cpp
M	intern/cycles/render/svm.h

===================================================================

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);



More information about the Bf-blender-cvs mailing list