What are the best practices organizing your materials in a project?
Assuming project is of realistic style, and will require some complex shaders too.
I’m not fan of creating one huge master material for every need. My reasons are:
I believe it adds a lot of overhead shading models that don’t need most of the material features. Adding static switches may help to cut out some unneeded functionality, but if I’m correct this in fact will just compile separate shaders for every combination of switch states, and I’ve read it may lead to “shader explosion”. What is it and how it will affect performance? Link to StaticSwitchParameter in documentation
You cannot control Blend Mode this way, meaning that even surfaces that don’t need to be Masked/Translucent will still use the instruction counts needed for it. Right?
I feel like checking all check-boxes in material’s “Usage” roll-out in Material Editor is bad for memory performance. If someone can comment on this, please do so.
It can get huge, cumbersome to work with in Material Editor AND for artists in Material Instance Editor, potentially having switches just for one-off effects.
So, I decided to use several master materials. But what should guide my decision when separating them?
Separating translucent shader into it’s own Translucent Master Material seems to be the most obvious one. So is for Masked too.
Should I separate Materials by “Usage” separation in Material Editor? e.g. using 2 different materials in static and skeletal meshes, even if their node system stays the same, just with different check-boxes in Details panel?
Some FX that may appear only once in a game can have it’s own materials, that may allow some freedom when creating them.
Am I correct in my understanding of it and is there something else I should be aware off?
Make as many materials as you need, in fact some platforms (especially mobile) dont really like using a lot of instances. additionally, all those static switches and what not can cause a lot of overhead, and be unintentional bottlenecks if not used right.
so, make as many (master)materials as you need, and along the way if you know that a material can be tweaked trough an instance, or adding 2-3 new nodes to it, edit and adjust accordingly.
at realtimevfx.com we talked a lot about it, and there are quite a few threads on the forums, as well as youtube vids about it. general consensus is, make as many as you need, in the end it does not matter that much.
though simple things like a wall-texture master with some instances, floor master, etc will help with workflow.
Hi Luos,
Thank you for reply! Before I accept your answer, please give me some time to do a bit of research on the matter
Do you have any additional links where I can read a bit more about things you’ve mentioned? I honestly tried to look it up, but info seemed too scarce for me. I hope to have more details on:
Mobile platforms specifically don’t like to have a lot of instances? (this is news to me)
I’ve read that Static Switches causing “Shader Explosion”, is it what you referencing to as overhead? I couldn’t find any technical info about it.
General approach “make as many as you need” feels a bit carefree, but you maybe right
But doesn’t engine optimize loading of the same shader? In case it does, are the gains that negligible?
I might have somewhat misspoken, as it mainly involves instances with many static switches.
a lot of the information is actually mentioned in a mobile platform (console) Specific documentation which is not publicly available, but Ill paraphrase a few sentences:
“Complex materials can create a lot of shader permutations which can add up significantly to your
memory footprint and load time. (Can be hundreds of MBs.)
Make sure you keep permutations to a minimum, in Instanced Materials don’t override static switch
parameters if you don’t need to, this can duplicate shaders unnecessarily.”
“Use Instanced Materials where possible if the material is only adjusting a few parameters to avoid duplicates.”
“Static Switch Parameters can be used with Instanced Materials but should be limited in their use of overriding the static switch. This is because the override of a static switch will duplicate the material. For example, if you override one static switch, you will result in two materials. Overriding two will result in four materials and so on leading to exponential growth.”
I think this should explain it in a more decent fashion and should adress both your questions along with the question how carefree one should be when making materials.
As for the static switches, to keep them as optimal as possible, yet still explain potential bloat here is an example:
Make a master material with 2 switches. (A and B)
Depending on the setup lets just go with the fact that it could create four different setups of True/False:
A True, B True
A False B True
A True, B False
A False, B False
Now each of these four setups come with their own variables/parameters.
In this case you would want to make four instances from that master material with the aforementioned switches set up like that, these would be your main material instances, or “Master instances”.
so:
Master material (not used anywhere)
4 “Master instances” referencing the master material, each with a different configuration.
Now if you need the “Master instance” that has “A True, B True” but you need to change another variable (Color for instance)
You create a new instance from that “Master Instance”, creating a Material Instance Instance and change the color in this one, and apply to what you need.
As you can see, this can become really confusing really fast, especially with big teams, and that bloat is real if you do not pay attention.
Thank you, this already might help me to do more or less educated decisions when planning my materials.
If I understood correctly engine compiles/cooks only used combination of switches? In that case in a material with 2 switches, would it be possible to have only 3 shader permutations? (for example we never use a material with both switches set to true), or will it create a shader for [True,True] combination regardless?
Depending on this, having a big “master material” with many switches and only few “master instances” with set combination of switch states may seem like a viable setup. Artists will use “child instances” of “master instances” without touching switch parameters, and thus limiting amount of shaders compiled from “master material”. Is that correct?
Im not too experienced with the cooking process as someone else takes care of that in my case, but anything not used can be excluded, and even if its not excluded… if its not used it wont be loaded.
That also goes for instances that are not used in production.
I would not suggest to go for a massive master material, any edit you make will result in all shaders recompiling wasting precious time, and a small mistake is easily made. Imagine noticing all instances being broken. ouch.
It is viable, but at some point you are better off making a fresh master.
I personally tend to try and keep the amount of static switches to a minimum, and when I need more than three I will take a good gander to see if its better to split the two setups.