AcademySoftwareFoundation / AcademySoftwareFoundation/MaterialX

Unlit shader fails code generation when used with `<mix>` node.

Open
#2,015 8 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.