In addition to today’s “changing compiled shader format” thread, here’s another one with ideas / thoughts about shader loading performance.
Basically, shader loading is slow. And sometimes instantiating something at runtime with a new shader causes hiccups as well. A good question is, how to solve that?
We’ve looked at shader loading, and it seems that on the platforms where the problem is the worst (mobile), almost all time is spent not in our code. We can change our own shader serialization format (binary instead of text) and optimize loading code, but the truth is, 95% of time is spent in just glCompileShader + glLinkProgram. There’s not much we can do here, except to “load less shaders” or “load shaders later”.
So some ideas:
-
Reduce number of shader variants that are included into game to begin with (some UI somewhere to specify what kinds of lights/shadows/… you’ll need etc.). For 5.0 we’ve started doing this with lightmapping modes; soon with fog types; could also add more options like that.
-
This saves both game building time, game data size, makes loading faster and runtime memory usage smaller. The downside is, adds new settings somewhere, and if you get them wrong then some head scratching can occur.
-
Delay loading of shader variants until they are actually needed. Currently, typically 50-80% of shader variants are never needed in the game.
-
Can be a net win if there are many actually unused variants.
-
However, for variants that are actually used, this delays “load time” until “rendering time”, i.e. you just changed longer load time into a hiccup on first render.
-
Shader.WarmupAllShaders could probably be extended into “something better”. Good question is - to what?
-
Spawn some background thread and/or timesliced shader loading? Or some other approaches.
What’s your shader loading performance?
To understand the problem better, it would help to know what are your shader loading problems, and especially to know the numbers. For example:
- Which platforms you have shader loading problems on? Hiccups?
- Is it more important to load shaders faster, or to avoid hiccups at runtime?
- How many shaders do you typically have, and how many variants they have internally?
- Do you use Shader.WarmupAllShaders, and is the functionality ok for you? What you would like instead?
- When you have hiccups at runtime - is that because an object with a whole new shader came into view? Or just one of internal variants that was not used before? Does it happen on first play of the game, or on later runs as well?
- etc.
Feedback welcome!