How far should re-using shaders be taken?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By hexaquo

In https://docs.godotengine.org/en/3.2/tutorials/3d/3d_performance_and_limitations.html, it is stated that materials and shaders should be re-used as much as possible. To what extent should this be done for the best performance?

For example, take an LOD-based terrain system. Some things are always the same (e.g. applying the heightmap to the mesh), but higher LODs can have a lot of additional functionality. Should this be put into a single shader with a lot of branching, or split into 2-3 different shaders? From what I’ve heard, branching in shaders doesn’t necessarily help performance, so I’d tend towards splitting it up, but the docs also say that re-using materials has very high priority…

If anyone has benchmarks or heuristics regarding this, that’d be very helpful!

:bust_in_silhouette: Reply From: Zylann

To what extent should this be done for the best performance?

It should be done if your average target device has unnacceptable FPS. That said, lots of things can affect performance, re-using shaders and materials is just one thing to try when optimizing.

For your terrain example, it’s true that the most advanced terrain systems use multiple shader variants for close and far range, but it’s not always necessary. If you were to do this, it’s quite some work as terrains have particular kinds of shaders and you have to blend between two as well. Finally, that would only be 1, 2, maybe 3 shaders. Quite nothing compared to everything that goes on top of it.

In Vulkan those things get better but keeping material count low is still means less work for the renderer.
I don’t have a particular benchmark to link, it would be interesting to create one with concrete examples because it’s not immediately obvious what parameters of a SpatialMaterial will significantly change the actual shader behind it, and by how much the difference would be.