Skip to content

Commit dc337ca

Browse files
Propose an initial graph refactoring framework for shader generation (#2832)
This changelist proposes an initial graph refactoring framework for MaterialX shader generation, replacing hardcoded graph optimizations with a composable set of named refactoring passes. The following specific changes are included: - Add a `ShaderGraphRefactor` base class, with three concrete subclasses for node elision, premultiplied BSDF add (valuable in hardware languages), and layer-over-mix distribution (valuable in MDL). - Add a virtual `setDefaultOptions` method to `ShaderGenerator`, enabling each subclass to set target-appropriate defaults at `GenContext` construction time. - Add a `MIX` classification bit to ShaderNode for efficient mix node identification. - Remove hand-authored GLSL and MDL graph overrides for `open_pbr_surface` and `standard_surface`, as these refactoring steps are now generated automatically.
1 parent 2ae3121 commit dc337ca

20 files changed

Lines changed: 663 additions & 1633 deletions

File tree

libraries/bxdf/genglsl/open_pbr_surface.mtlx

Lines changed: 0 additions & 597 deletions
This file was deleted.

libraries/bxdf/genglsl/standard_surface.mtlx

Lines changed: 0 additions & 343 deletions
This file was deleted.

libraries/bxdf/genmdl/open_pbr_surface.mtlx

Lines changed: 0 additions & 594 deletions
This file was deleted.

source/JsMaterialX/JsMaterialXGenShader/JsGenOptions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ EMSCRIPTEN_BINDINGS(GenOptions)
3636
.property("targetDistanceUnit", &mx::GenOptions::targetDistanceUnit)
3737
.property("addUpstreamDependencies", &mx::GenOptions::addUpstreamDependencies)
3838
.property("emitColorTransforms", &mx::GenOptions::emitColorTransforms)
39+
.property("elideConstantNodes", &mx::GenOptions::elideConstantNodes)
40+
.property("premultipliedBsdfAdd", &mx::GenOptions::premultipliedBsdfAdd)
41+
.property("distributeLayerOverBsdfMix", &mx::GenOptions::distributeLayerOverBsdfMix)
3942
.property("hwTransparency", &mx::GenOptions::hwTransparency)
4043
.property("hwSpecularEnvironmentMethod", &mx::GenOptions::hwSpecularEnvironmentMethod)
4144
.property("hwDirectionalAlbedoMethod", &mx::GenOptions::hwDirectionalAlbedoMethod)

source/MaterialXGenHw/HwShaderGenerator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ HwShaderGenerator::HwShaderGenerator(TypeSystemPtr typeSystem, SyntaxPtr syntax)
8989
_tokenSubstitutions[HW::T_CLOSURE_DATA_CONSTRUCTOR] = HW::CLOSURE_DATA_CONSTRUCTOR;
9090
}
9191

92+
void HwShaderGenerator::applyDefaultOptions(GenOptions& options) const
93+
{
94+
ShaderGenerator::applyDefaultOptions(options);
95+
options.premultipliedBsdfAdd = true;
96+
}
97+
9298
ShaderPtr HwShaderGenerator::createShader(const string& name, ElementPtr element, GenContext& context) const
9399
{
94100
// Create the root shader graph

source/MaterialXGenHw/HwShaderGenerator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ class MX_GENHW_API HwShaderGenerator : public ShaderGenerator
4343
void emitClosureDataArg(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
4444
void emitClosureDataParameter(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
4545

46+
/// Apply the default GenOptions for hardware shader generation.
47+
void applyDefaultOptions(GenOptions& options) const override;
48+
4649
/// Logic to indicate whether code to support direct lighting should be emitted.
4750
/// By default if the graph is classified as a shader, or BSDF node then lighting is assumed to be required.
4851
/// Derived classes can override this logic.

source/MaterialXGenMdl/MdlShaderGenerator.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ MdlShaderGenerator::MdlShaderGenerator(TypeSystemPtr typeSystem) :
125125
registerImplementation("IM_image_vector4_" + MdlShaderGenerator::TARGET, ImageNodeMdl::create);
126126
}
127127

128+
void MdlShaderGenerator::applyDefaultOptions(GenOptions& options) const
129+
{
130+
ShaderGenerator::applyDefaultOptions(options);
131+
options.distributeLayerOverBsdfMix = true;
132+
}
133+
128134
ShaderPtr MdlShaderGenerator::generate(const string& name, ElementPtr element, GenContext& context) const
129135
{
130136
// For MDL we cannot cache node implementations between generation calls,

source/MaterialXGenMdl/MdlShaderGenerator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ class MX_GENMDL_API MdlShaderGenerator : public ShaderGenerator
7070
/// Return a unique identifier for the target this generator is for
7171
const string& getTarget() const override { return TARGET; }
7272

73+
/// Apply the default GenOptions for MDL shader generation.
74+
void applyDefaultOptions(GenOptions& options) const override;
75+
7376
/// Generate a shader starting from the given element, translating
7477
/// the element and all dependencies upstream into shader code.
7578
ShaderPtr generate(const string& name, ElementPtr element, GenContext& context) const override;

source/MaterialXGenShader/GenContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ GenContext::GenContext(ShaderGeneratorPtr sg) :
2020
throw ExceptionShaderGenError("GenContext must have a valid shader generator");
2121
}
2222

23+
// Apply the generator's default options for its target.
24+
_sg->applyDefaultOptions(_options);
25+
2326
// Collect and cache reserved words from the shader generator
2427
StringSet reservedWords;
2528

source/MaterialXGenShader/GenOptions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class MX_GENSHADER_API GenOptions
8282
libraryPrefix("libraries"),
8383
emitColorTransforms(true),
8484
elideConstantNodes(true),
85+
premultipliedBsdfAdd(false),
86+
distributeLayerOverBsdfMix(false),
8587
hwTransparency(false),
8688
hwSpecularEnvironmentMethod(SPECULAR_ENVIRONMENT_FIS),
8789
hwDirectionalAlbedoMethod(DIRECTIONAL_ALBEDO_ANALYTIC),
@@ -141,6 +143,17 @@ class MX_GENSHADER_API GenOptions
141143
/// Enable eliding constant nodes. Defaults to true.
142144
bool elideConstantNodes;
143145

146+
/// Enable replacing BSDF mix nodes with premultiplied add nodes.
147+
/// This folds the mix weight into each BSDF's weight input, enabling
148+
/// hardware shading languages to skip BSDF evaluation via dynamic
149+
/// branching when the weight is zero. Defaults to false.
150+
bool premultipliedBsdfAdd;
151+
152+
/// Enable distributing layer operations over mix nodes.
153+
/// Transforms layer(mix(A, B, w), C) into mix(layer(A, C), layer(B, C), w)
154+
/// for backends with limited layering capabilities. Defaults to false.
155+
bool distributeLayerOverBsdfMix;
156+
144157
/// Sets if transparency is needed or not for HW shaders.
145158
/// If a surface shader has potential of being transparent
146159
/// this must be set to true, otherwise no transparency

0 commit comments

Comments
 (0)