Forced shader compilation


I’ve added forced shader compilation for the Shaders scene. It didn’t take long, but it took some trial and error. Be warned, I am in no way an expert on this topic. Here are my notes.

The problem

The problem here, I assume, is that the Compatibility renderer has very slow shader compilation times. Every time that a new shader needs to be shown on the screen, the game stutters a little while compiling the shader to create a cache file. Once cached, shaders don’t create stutters anymore.

Steps I took

So what I did was :

  • Saved each ShaderMaterial that was used in the scene to a resource file. (I assume this would be the longest task in an established workflow)
  • Created a new resource script to store an array of ShaderMaterials. The class is called ShaderMaterialList.
  • Created a new ShaderMaterialList resource and added all the saved ShaderMaterial resources to it. You can select all of them at once and drag them into the Inspector of ShaderMaterialList.
  • In the scene script, I looped through this resource and I created a ColorRect assigning the looped ShaderMaterial to it.
  • Added the ColorRect to the scene. I changed the minimum size so that it is visible.
  • Added a very short timer (0.01 sec) so that a progress bar can update.
  • When I finish looping through the array, I hide the ColorRects and show the scene containing the shaders resulting in no stutter. You can also delete the ColorRects if you want.

This doesn’t remove the time needed to compile the shaders obviously, but it hides the big stutter from loading a lot of shaders at once behind a progress bar and allows the developer to force the compilation of shaders at once (at the beginning of the scene for example) instead of having small stutters all throughout the game.

More notes*

  • The ColorRects need to be visible. They need to be seen by the camera and they can’t be the size Vector2(0, 0).
  • The ColorRects can be set to be nearly invisible if you want to hide them. Set the alpha to a very small value for example.
  • Something I read was that rotating the camera can help with the compilation of shaders, but I haven’t tested this, nor did I feel the need to implement it.
  • You can test the loading in the browser tool : click on Shaders -> wait for compilation -> click on Back -> click on Shaders again -> ??? -> Profit.
  • You can also try opening the Particles scene. You will notice that since there is no progress bar, it feels like the game freezes the first time that you open the scene. It opens instantly afterwards.
  • Since there is an artificial timer set to update the progress bar, you can set a global flag and not loop through the resource each time that the scene is loaded.
  • You can create multiple ShaderMaterialList resources to group shaders by scene and force compile those shaders when the scene loads.
  • You can also loop through the node tree, grab every ShaderMaterial that is in there, and do it that way.

This is the commit where this feature was first added and where you can find all the related files, sorry that it is coupled with some reorganization. Important files are shaders.tscn, shaders.gd, shader_material_list.gd, and shader_material_list.tres.

Get Web export test tool for Godot 4.2

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.