AcademySoftwareFoundation / AcademySoftwareFoundation/MaterialX
Unlit shader fails code generation when used with `<mix>` node.
- Dominant language
- C++
- Stars
- 2.3k
- Forks
- 451
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 8
Description
Given the following material:
```
```
Generating the OSL shader code yields this the following abbreviated code.
```
closure color null_closure = 0;
surfaceshader convert_color3_surfaceshader_out = surfaceshader(null_closure, null_closure, 1.0);
NG_convert_color3_surfaceshader(convert_color3_surfaceshader_in, convert_color3_surfaceshader_out);
surfaceshader mix_surfaceshader_out = surfaceshader(null_closure, null_closure, 1.0);
mx_mix_surfaceshader(surface_unlit_out, convert_color3_surfaceshader_out, mix1, mix_surfaceshader_out);
out = mix_surfaceshader_out;
```
The `surface_unlit_out` variable is missing. This is due to the code generation for the mix surfaceshader node
emitting calls for its inputs with the CLOSURE classification (see [here](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/source/MaterialXGenShader/Nodes/ClosureSourceCodeNode.cpp#L24)) which unlit shaders don't have.
On initial investigations this could be resolved by changing the code in [`ShaderNode.cpp`](https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/source/MaterialXGenShader/ShaderNode.cpp#L240).
```
diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp
index ff3c8fdb..91396053 100644
--- a/source/MaterialXGenShader/ShaderNode.cpp
+++ b/source/MaterialXGenShader/ShaderNode.cpp
@@ -235,13 +235,10 @@ ShaderNodePtr ShaderNode::create(const ShaderGraph* parent, const string& name,
}
else if (*primaryOutput->getType() == *Type::SURFACESHADER)
{
+ newNode->_classification = Classification::SHADER | Classification::SURFACE | Classification::CLOSURE;
if (nodeDefName == "ND_surface_unlit")
{
- newNode->_classification = Classification::SHADER | Classification::SURFACE | Classification::UNLIT;
- }
- else
- {
- newNode->_classification = Classification::SHADER | Classification::SURFACE | Classification::CLOSURE;
+ newNode->_classification |= Classification::UNLIT;
}
}
else if (*primaryOutput->getType() == *Type::LIGHTSHADER)
```
With this patch then we generate valid OSL code.
```
closure color null_closure = 0;
surfaceshsader surface_unlit_out = surfaceshader(null_closure, null_closure, 1.0);
ix_surface_unlit(surface_unlit_emission, surface_unlit_emission_color, surface_unlit_transmission, surface_unlit_transmission_color, surface_unlit_opacity, surface_unlit_out);
surfaceshsader convert_color3_surfaceshader_out = surfaceshader(null_closure, null_closure, 1.0);
NG_convert_color3_surfaceshader(convert_color3_surfaceshader_in, convert_color3_surfaceshader_out);
surfaceshsader mix_surfaceshader_out = surfaceshader(null_closure, null_closure, 1.0);
mx_mix_surfaceshader(surface_unlit_out, convert_color3_surfaceshader_out, mix1, mix_surfaceshader_out);
out = mix_surfaceshader_out;
```
But then I found Issue #839 - which then made me wonder if this incompatibility is intentional? The issue appears to describe the `` material as a container for non-pbr style materials, that perhaps is intentionally incompatible with the `pbrlib` nodes. If this is the case then I think we should update the specification to disallow the combination of `` with other `pbrlib` nodes, and then also introduce some sort of validation to report to the user if they unintentionally combine these two incompatible concepts.
Contributor guide
Research direction
Start with ShaderNode::create in source/MaterialXGenShader/ShaderNode.cpp and the closure handling in source/MaterialXGenShader/Nodes/ClosureSourceCodeNode.cpp. Reproduce the supplied MaterialX document and inspect the generated OSL around the mix surfaceshader inputs, then review Issue #839. Done means the intended compatibility is established and the issue has either a validated generation fix or an explicit specification and validation outcome.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100