How to handle version changes to UMaterialExpression nodes?

I like how UMaterialExpression allows me to write code which hides internal complexity from Materials as well as avoids issues with code/data dependencies. However, a big problem that I am wrestling with is knowing how to force materials to recompile properly when I need to extend functionality within the expression or fix bugs. I don’t understand enough of the lower level logic for what causes materials to recognize that the shaders they generated must be not use any pre-cached artifacts. It sure seems like a virtual on UMaterialExpression which had some sort of versioning scheme would be exactly what I want so that as I change how Complie() works I can just bump a version. The solution cannot require that I place a new expression in any existing materials because that would be a new expression guid which would cause all of our MaterialInstance assets to break.

I’m never really confident I understand what shader I’m actually looking at. In the editor, Compile() gets called whenever I load the Material and things work, however in cooked builds it sure appears that I’m using shaders that are an older version of the code as it evolves - like when I cook it’s pulling from some DDC for the shader compile that does not reflect my latest version of what Compile() does. If I enable symbols to attempt to debug what the shader is, it also fixes itself because that forces a recompile of the shaders at cook time. Currently my workflow is to nuke my Saved and DDC directories to try to force full recompiles of everything all the time, which is extremely slow and heavy handed.

I’m also never confident that when I make changes to our module which includes the UMaterialExpression types that everybody else on our team will properly generate shader code correctly due to my own local inability to get the right shaders being built.

Is there a better way to make changes to existing UMaterialExpression?

Steps to Reproduce
N/A

Hi Ryan,

Materials do not have an auto invalidation system based on the state of their content: if anything a material depends on changes and would require the material to re-translate, this needs to be done manually by opening and resaving the material.

If the change you make are code-related, for instance because you’re changing how a UMaterialExpression is built, or you make a change to the translator, you need to bump the material DDC key. Look for ‘MaterialTranslationDDCVersion’ and bump it to a different GUID. This will cause all materials to be invalidated and retranslated/compiled.

I hope this helps.

-Massimo

I understand. We don’t have a per-expression “checksum” at the moment, but that is an interesting idea. Thank you for the suggestion.

Okay, I was hoping for something more targetted to just those materials which use the node in question. Thank you