Skip to content

Commit d7771b3

Browse files
Fix bug in BSDF code gen for HW languages (AcademySoftwareFoundation#1399)
This change list fixes a bug in code gen for HW languages, where under certain conditions the function call for a BSDF node could be generated multiple times in the same scope. For example, if a pure reflection BSDF node, like oren_nayar_bsdf, where referenced multiple times in a graph. Then during generation of the transmission section of a GLSL surface shader the node's output variable would be emitted multiple times, giving erroneous code. A workaround was previously to duplicate the node in the graph, as for example done in the GltfPbr graph. With this fix duplication is no longer needed.
1 parent 2a9b37a commit d7771b3

4 files changed

Lines changed: 15 additions & 10 deletions

File tree

libraries/bxdf/gltf_pbr.mtlx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,6 @@
148148
<!-- Thin-film + Dielectric
149149
Note: Due to limitations in codegen, the base layer BSDF is duplicated (#1035). -->
150150

151-
<oren_nayar_diffuse_bsdf name="tf_diffuse_bsdf" type="BSDF">
152-
<input name="color" type="color3" interfacename="base_color" />
153-
<input name="normal" type="vector3" interfacename="normal" />
154-
</oren_nayar_diffuse_bsdf>
155-
156151
<dielectric_bsdf name="tf_transmission_bsdf" type="BSDF">
157152
<input name="weight" type="float" value="1" />
158153
<input name="tint" type="color3" interfacename="base_color" />
@@ -173,7 +168,7 @@
173168
</generalized_schlick_bsdf>
174169

175170
<mix name="tf_transmission_mix" type="BSDF">
176-
<input name="bg" type="BSDF" nodename="tf_diffuse_bsdf" />
171+
<input name="bg" type="BSDF" nodename="diffuse_bsdf" />
177172
<input name="fg" type="BSDF" nodename="tf_transmission_bsdf" />
178173
<input name="mix" type="float" interfacename="transmission" />
179174
</mix>

source/MaterialXGenShader/HwShaderGenerator.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ void HwShaderGenerator::emitFunctionCall(const ShaderNode& node, GenContext& con
500500
emitLineBegin(stage);
501501
emitOutput(node.getOutput(), true, true, context, stage);
502502
emitLineEnd(stage);
503+
504+
// Register the node as emitted, but omit the function call.
505+
stage.addFunctionCall(node, context, false);
503506
}
504507
}
505508

source/MaterialXGenShader/ShaderStage.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,14 +365,18 @@ void ShaderStage::addFunctionDefinition(const ShaderNode& node, GenContext& cont
365365
}
366366
}
367367

368-
void ShaderStage::addFunctionCall(const ShaderNode& node, GenContext& context)
368+
void ShaderStage::addFunctionCall(const ShaderNode& node, GenContext& context, bool emitCode)
369369
{
370+
// Register this function as being called in the current scope.
370371
const ClosureContext* cct = context.getClosureContext();
371372
const FunctionCallId id(&node, cct ? cct->getType() : 0);
372-
373373
_scopes.back().functions.insert(id);
374374

375-
node.getImplementation().emitFunctionCall(node, context, *this);
375+
// Emit code for the function call if not omitted.
376+
if (emitCode)
377+
{
378+
node.getImplementation().emitFunctionCall(node, context, *this);
379+
}
376380
}
377381

378382
bool ShaderStage::isEmitted(const ShaderNode& node, GenContext& context) const

source/MaterialXGenShader/ShaderStage.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@ class MX_GENSHADER_API ShaderStage
265265
void addFunctionDefinition(const ShaderNode& node, GenContext& context);
266266

267267
/// Add the function call for the given node.
268-
void addFunctionCall(const ShaderNode& node, GenContext& context);
268+
/// This will register the function as being called in the current scope, and code for the
269+
/// function call will be added to the stage. If emitCode is set to false the code for the
270+
/// function call will be omitted.
271+
void addFunctionCall(const ShaderNode& node, GenContext& context, bool emitCode = true);
269272

270273
/// Return true if the function for the given node has been emitted in the current scope.
271274
bool isEmitted(const ShaderNode& node, GenContext& context) const;

0 commit comments

Comments
 (0)