BSDF and Surfaceshader Scene Objects
@dmccann-dwa is already working on this.
Since Oct 2, 2026.
Assessment
This issue has not been assessed yet.
Description
Scope
We're implementing Mtlx_Surface with arbitrarily mixable and layerable BSDF components. It can be mixed with other Surfaceshaders, like Mtlx_Standard_Surface_Surfaceshader. These are usable in C++ and ISPC.
Upon scene creation, the assigned shader will walk its input graph to discover the Surfaceshader's lobes and ordering. It then creates a mapping from BSDF nodes to a data buffer. BSDFs using the same shading model are combined wherever possible, and their respective inputs blended accordingly.
During shading, this buffer will be populated by input data, then interpreted as BSDF components (see moonray/lib/rendering/shading/BsdfComponent.h) and sent to the BsdfBuilder for evaluation.
Development Branches
Branches are currently internal. Link coming soon!
Limitations
Core Moonray requires the following material models to be implemented to meet MaterialX specification:
- Fuzz and Zeltner Fuzz
- Burley Diffuse
A full implementation of the Add operator will require core Moonray changes. We currently only support adding individual lobes, as opposed to adding a physically-layered set of lobes.
Current Progress & Priority
Implemented several BSDF components, Mix, Layer, Multiply operators. Standard Surface, MixSurfaceshader.
The highest priority is testing and profiling. We need to understand the overhead of the API as it wraps MoonRay's existing BSDFBuilder. The first proposed test is to compare the following:
- A graph of BSDFs and operators that constitutes the Autodesk Standard Material
- The same material implemented as a single shader with direct calls to BSDFBuilder
API and algorithm design
BSDFs, or partial materials, are a new notion for MoonRay. As new scenegraph objects, the first definition is in Scene_RDL2. Surfaceshaders, as assignable materials, are simply defined in the Materialx_shaders repository to extend the material scenegraph object.
This section explains the basic API, and the utility objects to handle dynamic shading data.
All BSDF classes are responsible for implementing the following:
public:
// save the type of this BSDF (or this shader's child BSDFs) and its path to the slab manager
bool registerSlab(MtlxTreeTraversal& treeTraversal,
MtlxSlabManager& slabManager) const override;
private:
// evaluate input data for shading
static void resolveParameters(
const MtlxBsdf* self,
const moonray::shading::MtlxSlabManager& slabManager,
moonray::shading::MtlxTreeTraversal& treeTraversal,
moonray::shading::TLState *tls,
const moonray::shading::State& state,
const float weight,
const Color& tint,
moonray::shading::MtlxSlabShadingData& out);
Surfaceshaders must also implement analogous functions. In their material::shade() function, they instantiate all of the utility objects and begin traversing the BSDF tree.
Utility Objects: MtlxSlabShadingData & Others
MtlxSlabManager is the core of the dynamic shading API. The assignable material is conceptualized as a composite of horizontally-blended (mixed) or vertically-blended (layered) slabs. During scene creation, a MtlxSlabManager is instantiated in a surfaceshader then passed to child BSDF objects through registerSlab(), which builds a surjective mapping of BSDF shaders to slabs. This mapping is surjective in order to blend parameters of matching lobes, to minimize the number of lobes the path tracer must evaluate.
This mapping is made and accessed using the shading graph path from the MtlxSlabManager's owner and the respective BSDF, encoded by the MtlxTreeTraversal class.
During shading, this mapping is used to write into and read from MtlxSlabShadingData. This is a simple container of serialized data, made to be compatible with ISPC. When a shader writer implements resolveParameters(), it ends with the following pattern:
const BRDF myBRDF = ... // pack evaluated data into moonray/lib/rendering/shading/BsdfComponent.h struct
slabManager.addSample(myBrdf, weight, tint, treeTraversal.getPath(), out);
The MtlxSlabManager will then weight and tint the appropriate data as it is serialized. As the parent surfaceshader finishes querying all of the BSDF components it owns, MtlxSlabmanager will deserialize the data into components for MoonRay's BsdfBuilder (moonray/lib/rendering/shading/BsdfBuilder.h) in order of energy conservation (top layer slabs --> substrate layer slabs.)
- Dominant language
- CMake
- Stars
- 4.7k
- Forks
- 321
- Avg merge
- 13m
- Merged PRs (30d)
- 3
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OpenMoonRay/openmoonray
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
OpenMoonRay/openmoonray#332 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
OpenMoonRay/openmoonray#320 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
OpenMoonRay/openmoonray#233 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 57/100
OpenMoonRay/openmoonray#331 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 68/100
OpenMoonRay/openmoonray#330 ·