Skip to content

Commit

Permalink
Lobe pruning shader optimization
Browse files Browse the repository at this point in the history
Introduces the lobe pruning concept to MaterialX shaders generated by
either MayaUSD or LookdevX.

We look into shader graph implemnetation and find where we can cut the
graph to simplify it based on the value of the main lobe attributes.

This means a shader with a subsurface weight of zero will completely
prune the evaluation of the subsurface, while a value of 1 will
completely prune the evaluation of the dielectric base.

This provides interesting performance values:

```
MayaUSD: Tumbling speed of a stage with a 11x11x11 set of cubes with a red OpenPBR shader

                initial  optimized
Default light   434fps   441fps
Dome light       17fps   115fps

LookdevX/MaterialX: Tumbling speed of a heavy geometry scene from MAYA-136105 using OpenPBR surface

                initial  optimized
Default light   192fps   476fps
Dome light      7.6fps    65fps
```

Technical side: The code looks for nodes in the nodegraph implementation and checks any node that directly connects to the interface on a 0-1 slider:
- Mix nodes: If the mix value if 0 or 1, forward the value/connection of the bg or fg port to the node directly upstream. Delete node.
- Multiply nodes: If any value is zero, write zero to the corresponding port on the upstream node. Delete node.
- PBR nodes: If the weight parameter is zero, substitute with a no-op PBR node. Delete node.
This makes sure the ShaderGen works on a reduced codebase and greatly reduces code size and complexity by disconnecting unused subgraphs and skipping black PBR calls.
  • Loading branch information
JGamache-autodesk committed Nov 27, 2024
1 parent b3afd64 commit 435b234
Show file tree
Hide file tree
Showing 12 changed files with 1,063 additions and 6 deletions.
3 changes: 3 additions & 0 deletions lib/mayaUsd/render/MaterialXGenOgsXml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ target_sources(${PROJECT_NAME}
OgsFragment.cpp
OgsXmlGenerator.cpp
ShaderGenUtil.cpp
LobePruner.cpp
Nodes/SurfaceNodeMaya.cpp
Nodes/TexcoordNodeMaya.cpp
Nodes/MayaDarkClosureNode.cpp
PugiXML/pugixml.cpp
)

Expand Down Expand Up @@ -55,6 +57,7 @@ set(HEADERS
OgsFragment.h
OgsXmlGenerator.h
ShaderGenUtil.h
LobePruner.h
)

# -----------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "GlslFragmentGenerator.h"

#include "Nodes/MayaDarkClosureNode.h"
#include "Nodes/MayaShaderGraph.h"
#include "Nodes/SurfaceNodeMaya.h"
#include "Nodes/TexcoordNodeMaya.h"
Expand All @@ -24,6 +25,7 @@

#include <mayaUsd/render/MaterialXGenOgsXml/CombinedMaterialXVersion.h>
#include <mayaUsd/render/MaterialXGenOgsXml/GlslOcioNodeImpl.h>
#include <mayaUsd/render/MaterialXGenOgsXml/LobePruner.h>
#include <mayaUsd/render/MaterialXGenOgsXml/OgsXmlGenerator.h>

#include <MaterialXGenGlsl/GlslShaderGenerator.h>
Expand Down Expand Up @@ -208,6 +210,13 @@ GlslFragmentGenerator::GlslFragmentGenerator()
"IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, TexcoordNodeGlslMaya::create);
}

registerImplementation(
MaterialXMaya::ShaderGenUtil::LobePruner::getDarkBaseImplementationName(),
MayaDarkClosureNode::create);
registerImplementation(
MaterialXMaya::ShaderGenUtil::LobePruner::getDarkLayerImplementationName(),
MayaDarkClosureNode::create);

// The MaterialX transform node will crash if one of the "space" inputs is empty. This will be
// fixed in 1.38.9. In the meantime we use patched nodes to replace those previously added in
// the base class.
Expand Down
Loading

0 comments on commit 435b234

Please sign in to comment.