How to make sure all shaders are pre-cached to avoid lag spikes?

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

I’ve noticed my game has a lag spike whenever an object using a unique material is shown on screen for the first time.

I’ve read up and learned that OpenGL is “lazily” compiling the shaders when the game is already running, so a when an object using a previously unused material appears, that frame needs to wait until the shader is compiled before it can be rendered - hence stopping the game dead in it’s tracks until the shader is ready.

I think these lag spikes are unacceptable as they completely break the flow of the game. So far the only solutions I’ve heard is to render a frame with all the materials we’ll be using in our game to force the shader compilation at the beginning, so they are ready for later.

That sounds like a very crude workaround.

I believe there has to be a better way to deal with this issue. So what is it?

1 Like
:bust_in_silhouette: Reply From: Zylann

So far the only solutions I’ve heard is to render a frame with all the materials we’ll be using in our game to force the shader compilation at the beginning, so they are ready for later.

No you are right, that’s basically the simplest way you would do it in OpenGL. I believe improvements are coming with Vulkan since shaders can be handled differently.
For more information, this was discussed at length here: https://github.com/godotengine/godot/issues/13954

That’s kinda… weird.

I’ve also noticed that GPU particle effects (which are driven by shaders too) cause big lag spikes. So should I spawn all the game assets when it loads fro one frame let it lag, and be done with it?

Well, looking forward to see the 4.0 I guess…

unfa | 2020-06-03 21:04

You need to use a quad and force the renderer to draw each material your game will use. For particle materials, use a particle node. You can do that even hiding it behind a loading screen or an off-screen 1x1 viewport (Godot won’t cull it if it’s still in front of the camera).

Zylann | 2020-06-03 21:55

And now you know why loading screens are a thing.

Wakatta | 2020-09-06 11:45

Ok so would i need to loop through every material for that level and keep the quad in this viewport? or i guess i could do remove_child and all materials will stay? i was gunna say can i do this at the title screen for all levels but that would load every texture into memory? so… not a good idea?

bertodelrio256 | 2022-07-08 18:41