From the initial responses, this was what I was leaning toward. Glad to see you and others reiterate that line of thinking!
Anything that doesnāt change due to a switch doesnāt need to be recalculated.
So if you have multiple switches, its best to make a material instance for each potential switch setup (or better yet, only for those needed) and use that material instance as a āMaster Material Instanceā that way any instance that derives from this one doest need to recalculate the switch-changes.
You could see it as ābranchingā
Example: Screenshot - b50e13d4f3a91165ef5b49e8fa87a0ae - Gyazo
I personally might even start with a material instance to derive from instead of a master material, so any tweaks that need to be passed onto all the branches can be done in the instance to save some time.
that way I only need to go to the master material when its really necessary to tweak/adjust nodes.
As long as material instance is my base I see no gain in that. It is harder to spot a bug. it is in both cases separate shader in memory. There is a risk of not needed code. Also for fast tweaks and optimization it is easier to do it on material than to switch to another material instance or change its root. I personally saw big project on ue3 shipped to consoles and pc with even env shaders separated to each mesh Every approach is good as long as U are smart about it.
Untill your boss/client/lead tells you that they need a specific new node/material function/feature in ALL your effects (or anything really) and you need to manually add that into each material, instead of one master material and a handful of special cases.
Ive been there, and spending a day adding a new feature to almost 300 materials (I came into the project late, else this would never have happened) is not only mindnumbing frustrating, its also expensive. (time = money spend)
Also FYI: They are not seperate shaders in memory, any calculations done in the master get passed onto the instance.
That[quote=āLuos_83, post:24, topic:1035ā]
Untill your boss/client/lead tells you that they need a specific new node/material function/feature in ALL your effects (or anything really) and you need to manually add that into each material, instead of one master material and a handful of special cases.
[/quote]
That never happened to me in entire career. In Unreal U would just walk to programmer and add it to material class. And then disappear for a day not to feal wrath of 100k compilation for entire team.
Check in PIX or any other profiler. Only case when object dont reload shader is when U switch between 2 instances with exacly the same root. If only there is 1 switch changed - new shader is loaded.
Even in manual there is written: āa new version of the material must be compiled out for every used combination of static parameters in a materialā
Wow, this is a very interesting topic.
To support what @Marcin_Kazmierczak is saying, we are also working with a custom Ue and Iāve been told that a Master materials that has plenty of switches is basically (under the hood) the same approach of having multiples master materials since a new shader is created for every possible combinations.
As you guys said, it ends up being the technique you guys prefers for your workflow. Best case scenario I would also avoid the one master per particle emitter for reasons already been discussed but I like the philosophy of building one simpler master per type of effect so far (combined with function usages like @alex.underhill is suggesting). Itās easy to maintain and fast to iterate. The counter part is like @Luos_83 is explaining, it may be a pain to revisit all of them if needed. So far it has not been a major problem on our side but we already had to revisit a couple of master materials to add some functions.
So far, this means around 40-60 pretty simple master materials (they have few static switches inside them if they have any) to covers all of our VFX needs. ie: Flares, Smokes, Fires, Lightnings, Birds, Dust, Water splashes, etc.
I know that the number of shaders created could become a problem at some point. I guess because I donāt have the precise numbers for the specific VFX related shaders created it could create easily hundreds of shaders with all the changes in the materials instances. We are trying to find ways to have more precise numbers on the shaders created with our Materials. This will help us be a bit more responsible to really try to re-use before customizing a new material, material instance.
I heard that BF1 were using only 10-15 masters materials (canāt find the source info so Iām might be completely wrong here), Iām wondering if they were containing a lot of static switches that would anyway also generate a lot of shaders combinations in the engine or maybe they made the exercise of trying to make the most out of the fewest materials/shaders possible? That said I also know thet they donāt use the same tech so the workflow may be quite different anywayā¦
One thing to watch out for with static switches though, is that each branch is still compiled as a unique shader when you cook the build. If you have thousands of assets, all using switches, it can really bloat your shader overhead quickly.
We just ended up doing a pass on our props to remove all switches and go with prebuilt variants of what all those switch options represented as master materials. Youād think thisād be the same cost, but itās not, it drastically reduced our shader compiles and memory use. It also had the side advantage of letting us form a custom texture packing scheme for each variant, to save on texture memory.
VFX usually doesnāt have the same issues, more standardized material use cases and less overall asset counts, but in a large project it can hit the same problem.
Thanks for the info. I always enjoy learning more optimization tips and tricks. Iām sure there are some things we can cut down to their own materials, but we use probably 70% of our master materials functionality for most particles, in some capacity.
By that you mean only the used combinations, right? This is in the documentation:
āOn the other hand, a new version of the material must be compiled out for every used combination of static parameters in a material, which can lead to a shader explosion if abusedā
If it compiles all of the possible variations, even unused ones, then Iām screwed