I’m looking at this warning (pic below) in the UE documentation and I’m wondering the following…
If I’m using a dynamic material that has 3 booleans to change what’s selected. Is it therefore better to have 8 materials (222) with static bools and then just select the material I need vs 1 material with 3 static bool parameters?
With static bools I know each material will not run or compile the paths that are not selected (so if I have true selected it won’t run the instructions that are in the false path).
With static bool parameters it seems like it will compile every combination (so in this case 8 combinations) as the bools can be changed dynamically.
Let’s say I will ultimately use all 8 combinations but on different objects but each object will of course only use one of the combinations.
While static bool parameters are obviously better for workflow (1 material), I want to consider performance as I will use these materials a lot. I’ve currently been using static bools with multiple materials, but I wanted to make sure I’m not optimizing something that I
don’t need to. Does using static bool parameters compile every combination across each instance and in which case is it more performant to use different materials with static bools than 1 material with static bool parameters?
The warning you’re referring to is about the fact that dynamic branching (using dynamic parameters or functions) in materials can lead to decreased performance, as the engine has to evaluate the different branches at runtime.
In your case, you are trying to decide whether to use one material with multiple static bool parameters or multiple materials each with a single static bool.
Using multiple materials with static bools will result in better performance because the engine can compile each material with only the necessary instructions for the true path. This means that the instructions for the false path will not be compiled at all. (The drawback is however that there will be more draw calls or require more VRAM as you use more materials.)
On the other hand, using one material with multiple static bool parameters means that the engine has to compile all possible combinations of the bools, even if they are not used. This will lead to increased instruction count and potentially lower performance.
Sometimes having a master material is more performant than having multiple small materials as it will reduce draw calls. I hope this all made sense.
Thank you @EliasWick. This kinda makes sense, but does this happen at the instance level? Is each instance having to compile each possible combination or is that just done once for all instances?
Let’s say I have 80 instances in a level. I have the choice of 1 material with 3 static bool params, so 8 paths (222) to compile. Or 8 materials. The 80 instances are decals using dynamic materials. So, each decal will be unique (different roughness strengths, color tints textures etc.). But, all 8 combinations will be used by at least one of the decals.
Which option is better for performance? I’m thinking it’s more performant for each decal to use just the material it needs so have 8 materials, but my thinking assumes that for the alternative each of the 80 instances would have to compile all 8 paths of the single material option. If however, the engine itself is just compiling 8 combinations to cover all 80 decals and it isn’t at the instance level then the single material would be a better option as it’s only creating 8 combinations (not 80 x 8 combinations). Would you mind clarifying further?
In short, if your decals have unique material combinations, it’s best to use a unique material for each one. If the decals use only a subset of the possible combinations, then it’s better to use a single material with multiple parameter options. It’s worth noting that when you update any of the material inputs or parameters, the engine will recompile the MaterialInstance and update the Material Resource accordingly, regardless of how many instances use it.
When you have multiple instances of the same object in a scene, each instance can use a different MaterialInstance without incurring additional performance overhead. This is because the engine shares the same Material Resource across all instances that use the same MaterialInstance.
I can’t say which would be more performant as it will depend on the complexity and other factors. In your case I wouldn’t be too hung up on the subject and simply do this:
If the material is going to be super heavy with a lot of maths but few parameters, I would create one big material and create instances out of that one. If the material is going to be very lightweight, I might end up creating multiple materials if they are going to be differentiating from each other.
Thank you @EliasWick. Also, appreciate the resources you shared. Yeah, the big thing that has been confusing me is how static bool and static bool parameters impact performance.
But, as I’m creating Dynamic instances of my materials I assume that each decal is unique (diff params, tiling, textures etc.) so either way it’s going to create a new instance for every one - In my example above with 80 decals it will create 80 material instances as they are material instance dynamic and will have unique settings. I actually build them through construction script in a blueprint.
What I’m really trying to understand is that if I use a single master material and have 3 bool paths (so 8 combinations, 2^3) then would it just create 80 material instances or 640 (80*8) as each decal needs to compile each possible combination.
The weird thing is, I’ve tested using static bool parameters on a single material and looked at both the draw calls and shader complexity vs static bools on multiple materials and I don’t see a difference. The draw calls are the same (??) and the material with the static bool parameters only gets more expensive if I turn on the additional features. This would lead me to believe that there isn’t really a performance difference using static bool parameters and it’s much better for workflow. But that warning that I saw in the UE documentation was what had been worrying me that I’m missing something.
So, I’m currently under the understanding per above that with 80 unique dynamic material instances then whether I’m using 1 master material with static bool paramaters or multiple materials with static bools it’s still only going to compile 80 material instances not the 640 that I feared. Is that a correct summary?