Which method is more efficient?

Hello fellow artists and developers, I have a question for anyone who might have more experience than myself.

So, I’ve been reading through optimization guides while scouring the net and I pose this question:

Since my project only makes use of three master materials (Except for special circumstances like landscape, water, etc.) But easily 95% of all materials in my project are instances of the three master materials. I’ve also eliminated the need for the Static mask parameters by creating my own material function. It costs only a few more instructions than the mask parameter, but allows me to change the mask channel without the need to recompile the shader.

The only time an instance needs to recompile is when I need to change the shading model in the material instance. Although, I usually tend to stick with Default Lit, Subsurface, and Cloth shading. I have a translucent master setup, but it’s not yet optimized and therefore haven’t used it in a level until I fix it.

Two of the three master material use around 250 instructions. The third master material is a world aligned material that makes significant use of Luo’s absolutely invaluable World Aligned Texture and Rotation material functions. But it incurs a little less than 290 instructions, if memory serves correctly.

I also do not have any tessellation enabled. I feel like no matter what, the performance impact is too large to justify using it.

Now, I usually have anywhere from 1-6 different materials assigned to meshes when I import them, but said materials are immediately replaced by instances.

However, I don’t know if the performance cost that apparently comes with having more than one material per mesh is neutralized by the efficiency of my materials. Or if I would be better of creating Master materials with multiple material attributes.

Any insight on this would be greatly appreciated!

If each and every material you have possibly uses alpha mask layers, then you will not get any Early Z Occlusion benefits, because in general, graphics cards can’t/don’t do Early Z with materials that use alpha test or that use depth adjustment (like POM.) Thus, the material might seem efficient from an instruction count point of view, but it may cause rendering inefficiency. If you have large objects that will never use masking (such as brick walls, houses, tree trunks, etc) then it absolutely makes sense to build a specialized material that does no masking for those.

The inefficiency from multiple pieces comes from the cost of telling the graphics card to render with a particular material configuration. The cost is the “be done with the previous thing, here’s a new material, start drawing that” and thus is paid even if the materials would be solid primary colors :slight_smile:
That being said, the switching cost varies based on how different the materials are. If it’s the “same” material with different color parameters, that’s generally a cheaper switching cost, than if it’s a totally different material. Re-binding textures has varying cost – switching between textures of the same size, compression format, and sampler parameters is cheaper than switching to a texture with totally different parameters on many graphics cards.

So, in the end, you have to build realistic levels for your particular game, and actually measure the attributes you care about (frame rate, usually) with different options, on different graphics cards. Also, different cards (and form factors) have different trade-offs – some cards just want the shader instruction count to be low; other cards want to reduce overdraw as much as possible; yet other cards may be bound on other parameters. The only way to find out for YOUR particular game, is to carefully benchmark. (NVIDIA has some great tutorials on how to do this, using various tools that let you isolate various parts of the pipeline to see where your limitations are.)

Thank you very much for the insight!

I always avoid using the alpha channel because I personally don’t feel like I can justify the comparatively high cost for just one extra channel. Once I get home to my computer I will take a screenshot of how my material structure.

My general approach for textures is a Albedo and corresponding normal map. I put the Roughness, AO, and Metal maps into separate RGB channels of a third texture and use Linear color compression settings. When I need to use masks, like for decals, I do the same thing for decals of similar resolutions. Stick three into separate RGB channels. Then hook it up through my masking function to decide which one I want. I also make pretty extensive use of the BlendAngleCorrectedNormals function by setting it up so that I can make use of two detail normal maps on top of the primary normal map, and use UV scaling for each normal detail independently to be able to really come tune results. Otherwise, the rest of the functions are all math functions. Most of which are multiply, lerp, and Scalar parameter nodes. I think I have one power node, no divide, or anything like that.

I use multiple detail normal maps because it actually seems to work out cheaper. Since I can use the same detail normal maps in different combinations and different situations. Using two with different scaling values also really helps in getting rid of noticeable tiling texture repititions.

The thing about POM, though. That’s interesting. I honestly thought it was more akin to Normal mapping in that in that just creates the illusion of depth information instead of actually creating depth. However, if that is actually the case, than that makes much more sense. Because I have POM hooked up in my master material, but except for a few floor tile materials I never use it. So overall, do you think it would be cheaper to create a fourth, POM, specific material for the few cases that I do need it? So that it doesn’t impact the other 99%?

Also, the way you explained the multiple materials makes the whole issue much more comprehensible to me, so thank you very much for that! With that being said, I have a few follow up questions.

So, I understand that the shading model is the biggest determining factor as far as using multiple materials on a single mesh. But are there any particularly costly transitions? Like take a window mesh for example, you have the wooden border and molding assigned with a material that uses the Default Lit shading and then the second material for the glass uses the translucent shading model. Would that cost any more/less than something with a less extreme change? Like from the Default Lit to the Clothing shading model? Or is it essentially as expensive as any other change in shading model, (Aside from the preexisting costs that are inherent with each type of shader.)

Thank you very much for the insight!