Fix 1.38 normalmap frame input upgrade - #2994
Conversation
|
@tdavidovicNV I don’t share the assumption that the current algorithm is “patently” wrong, because, as you yourself state, the issue at hand is undefined behaviour. The upgrade algorithm was written under the assumption that an authored Just because the shader generation ignores the value, it does not mean that the behaviour is correct. |
|
@pablode good point, I re-read the spec and it is definitely less clear now than on the first reading (and even that required some transitive jumping through points). I was basing my take on the combination of:
The combination of these three, for me, meant very clearly that if there is no authored connection, then geomprop provides the connection.. and if there is a connection, it takes precedence over any value, turning the values irrelevant. (This is further supported by Houdini implementing it that way and emitting the shader example above). But I can see how a similar set of arguments can be used against this interpretation:
So in that way, the presence of value should make the And I would even agree that your interpretation makes more sense, because it is just weird that Practicioners note: Without the interpretation this fix implies, any assets from Houdini, up until at least 21.0.631 won't work, because it still puts the 0 value there: If we pivot to taking the interpretation of the upgrade algorithm over the ShaderGen, this stops working. But I totally agree it is a bigger question than I originally thought. (fwiw, I checked LookDevX, and it doesn't put the zeroes there, dunno if there is any other currently public production MaterialX tool) |
|
I'd say 2 things here:
|
|
Thanks for this fix, @tdavidovicNV, and thanks to @pablode for raising the interpretation question, which deserves a clear answer before this work goes forward. To ground the discussion, I tested the actual behavior of MaterialX 1.38, running the 1.38.10 release on a Houdini-style document with literal mx_normalmap_float(tex_normal_out, ..., geomprop_Nworld_out1, geomprop_Tworld_out1, mtlxnormalmap1_out);This holds even when the zeros are authored on nodegraph interface inputs, and the relevant logic in @pablode, your reading of the specification is very reasonable, and this discussion makes it clear that the current wording supports both interpretations. Since every MaterialX shader generator has implemented So I'd recommend the following interpretation going forward: an unconnected If that solution seems reasonable to you all, I'd recommend that we add test coverage for the new upgrade paths as part of this PR, e.g. in On your suggestion of clarifying the specification text, I fully agree, and I'd recommend that we make that a separate documentation PR following this one. |
|
Thanks @jstone-lucasfilm for the feedback. I have just two notes:
|
|
On my first note: I consider this resolved. ShaderGen has ignored unconnected values on defaultgeomprop inputs since 1.38, regardless of the value, so a zero-only exception would not preserve existing behavior. I pushed the required regression tests (well, examples), so we should be good to go on this. |
MaterialX 1.39 normalmap inputs use defaultgeomprop for the normal, tangent and bitangent frame inputs. Older 1.38 documents can still contain unconnected literal values on those inputs, often zeros from DCC exports (e.g., from Houdini). Shader generation treats unconnected defaultgeomprop inputs as geometric defaults rather than literal fallback values, so the upgrade path should preserve that behavior.
Example from the Teapot asset:
During the 1.38 to 1.39 upgrade, the existing code would take the literal
valuevalues, and cross them to build bitangent, which would be 0. This is patently wrong. We must remove unbound normal map inputs and let the 1.39 default geomprops take over.I would also recommend making this behavior even more clear in the spec, that
valueon a node that has default geomprop will be completely ignored:But that's not necessarily part of this PR.
Closes #2828.