forked from bartvdbraak/blender
Fix T84006: Cycles AOV not written with some mix shader node set ups
This commit is contained in:
parent
2601501fce
commit
dad5aded0c
@ -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 (ShaderNode *node, graph->nodes) {
|
||||||
foreach (ShaderInput *in, node->inputs) {
|
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
||||||
if (in->link != NULL) {
|
OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node);
|
||||||
ShaderNodeSet dependencies;
|
if (aov_node->slot >= 0) {
|
||||||
find_dependencies(dependencies, state->nodes_done, in);
|
aov_nodes.insert(aov_node);
|
||||||
generate_svm_nodes(dependencies, state);
|
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,
|
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 (!shareddeps.empty()) {
|
||||||
if (cl1in->link) {
|
if (cl1in->link) {
|
||||||
generated_shared_closure_nodes(root_node, cl1in->link->parent, state, shareddeps);
|
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 (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);
|
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 */
|
/* compile output node */
|
||||||
output->compile(*this);
|
output->compile(*this);
|
||||||
|
|
||||||
if (type == SHADER_TYPE_SURFACE) {
|
if (!state.aov_nodes.empty()) {
|
||||||
vector<OutputAOVNode *> aov_outputs;
|
/* AOV passes are only written if the object is directly visible, so
|
||||||
foreach (ShaderNode *node, graph->nodes) {
|
* there is no point in evaluating all the nodes generated only for the
|
||||||
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
* AOV outputs if that's not the case. Therefore, we insert
|
||||||
OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node);
|
* NODE_AOV_START into the shader before the AOV-only nodes are
|
||||||
if (aov_node->slot >= 0) {
|
* generated which tells the kernel that it can stop evaluation
|
||||||
aov_outputs.push_back(aov_node);
|
* early if AOVs will not be written. */
|
||||||
}
|
add_node(NODE_AOV_START, 0, 0, 0);
|
||||||
}
|
generate_svm_nodes(state.aov_nodes, &state);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +176,9 @@ class SVMCompiler {
|
|||||||
/* Set of closures which were already compiled. */
|
/* Set of closures which were already compiled. */
|
||||||
ShaderNodeSet closure_done;
|
ShaderNodeSet closure_done;
|
||||||
|
|
||||||
|
/* Set of nodes used for writing AOVs. */
|
||||||
|
ShaderNodeSet aov_nodes;
|
||||||
|
|
||||||
/* ** SVM nodes generation state ** */
|
/* ** SVM nodes generation state ** */
|
||||||
|
|
||||||
/* Flag whether the node with corresponding ID was already compiled or
|
/* Flag whether the node with corresponding ID was already compiled or
|
||||||
@ -197,6 +200,9 @@ class SVMCompiler {
|
|||||||
const ShaderNodeSet &done,
|
const ShaderNodeSet &done,
|
||||||
ShaderInput *input,
|
ShaderInput *input,
|
||||||
ShaderNode *skip_node = NULL);
|
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_node(ShaderNode *node, ShaderNodeSet &done);
|
||||||
void generate_aov_node(ShaderNode *node, CompilerState *state);
|
void generate_aov_node(ShaderNode *node, CompilerState *state);
|
||||||
void generate_closure_node(ShaderNode *node, CompilerState *state);
|
void generate_closure_node(ShaderNode *node, CompilerState *state);
|
||||||
|
Loading…
Reference in New Issue
Block a user