So I’m creating a master material for artists to create instances from and a question arises. When you use static switches to turn on or off things like specular, normal, emissive and all that jazz you basically end up creating multiple materials (one for each configuration of all the static switches) that get compiled at runtime. This kind of detracts from one of the points of having a master material (yes I know there are other reasons to have one but lets stick to just this one for now).
The alternative is to have a default texture plugged into each of those channels that basically gives them zero effect until the artist plugs in their own texture. Now you can have just one default texture (a 16x16 white block in my case), but because each of those is a parameter Unreal treats them as separate textures.
So my question is this: Is it better to have more materials or more (albeit small) textures in your scene?
I’ve done some profiling with stat memory and PIX on the xbox and the difference is not huge, but I’ve only got a few test meshes in my scene and before I take the time to try and build a whole scene to profile I wanted to get a few opinions and see if anyone can shed some light on the situation.
So switches are absolutely the way to roll. You’ll increase your shader cache memory because of the number of shaders you create (also, each individual usage flag i.e. bUsedwithStaticMeshes, bUsedWithSkeletal will increase the number as well), but you’ll save on your performance where those textures/instructions aren’t needed.
In our master materials, we use 2x2s or 4x4s for diffuse and normal (normal is separate so the artist will more quickly recognize if something is wrong), and specular/emissive will use the diffuse texture as well in the parameters. The cost here is pretty negligible on most platforms (although the Xbox treats textures a bit differently) and it allows us to quickly find when a material instance is reference a default texture that can have the switch for normal or spec removed.
If you have a 16x16 white texture in your normal map chain, you will still eat the instruction cost for absolutely no effect - this is so incredibly wasteful! I do a pass several times on our games where we look for materials that have the default textures set on the material instances and turn off those switches.
That works for environment meshes/skeletal meshes. Effects materials are a bit of a different story. We have a few master shaders there, but the unique number of additions for materials means the majority of our shader/material memory comes from our FX materials. This will end up being determined by the type of game you’re working on. Borderlands was high in effects materials but that was necessary because of all of our guns/enemies. There were just a few master shaders for our props - opaque, masked, a couple of special case ones created to save texture memory (i.e. hiding the specular in the blue channel of the normal map and deriving the spec if necessary), and a few others.
If you are CPU/Draw Call bound, having fewer shader permutations will help you (Multiply-Out).
If you are Fill Rate bound, having smaller shaders will help you (Switches).
Most games are one or the other. It depends on your game. If you have expensive shaders that fill most of the screen, Switches would probably be better. If you have a big variety of objects and materials and practically each one would need its own permutation, Multiply-Out may be better.
It also depends on target hardware, and engine.
The only way to know the answer to performance questions is to profile it on some more representative content. However if I had to make a blind suggestion it’d be to follow Strobel’s advice. Also as he says, effects are often a different story.