| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 | .. _doc_pipeline_compilations:Reducing stutter from shader (pipeline) compilations====================================================Pipeline compilation, also commonly known as shader compilation, is an expensiveoperation required by the engine to be able to draw any kind of content with theGPU... figure:: img/pipeline_compilations_shader_compilation_diagram.webp   :align: center   :alt: Flowchart showing the entire compilation process for a shader: VisualShader and Standard Material to Godot Shading Language to GLSL to Intermediate Format (SPIR-V) to Pipeline. Shader Compilation is the GLSL to Intermediate Format step. Pipeline Compilation is the Intermediate Format to Pipeline step.   Shaders and materials in Godot go through several steps before they can be run   by the GPU.In more precise terms, *shader compilation* involves the translation of the GLSLcode that Godot generates into an intermediate format that can be shared acrosssystems (such as SPIR-V when using Vulkan). However, this format can't be usedby the GPU directly.*Pipeline compilation* is the step where the GPU driver convertsthe intermediate shader format (the result from shader compilation) to somethingthe GPU can actually use for rendering. Drivers usually keep a cache ofpipelines stored somewhere in the system to avoid repeating the process everytime a game is run. This cache is usually deleted when the driver is updated.Pipelines contain more information than just the shader code, which means thatfor each shader, there can be dozens of pipelines or more! This makes itdifficult for an engine to compile them ahead of time, both because it would bevery slow, and because it would take up a lot of memory. On top of that, thisstep can only be performed on the user's system and it is very tough to sharethe result between users unless they have the exact same hardware and driverversion.Before Godot 4.4, there was no solution to pipeline compilation other thangenerating them when an object shows up inside the camera's view, leading to theinfamous *shader stutter* or hitches that only occur during the firstplaythrough. **With Godot 4.4, new mechanisms have been introduced to mitigatestutters from pipeline compilation.**- **Ubershaders**: Godot makes use of specialization constants, a feature that  allows the driver to optimize a pipeline's code around a set of parameters  such as lighting, shadow quality, etc. Specialization constants are used to  optimize a shader by limiting unnecessary features. Changing a specialization  constant requires recompiling the pipeline. Ubershaders are a special version  of the shader that are able to change these constants while rendering, which  means Godot can precompile just one pipeline ahead of time and compile the  more optimized versions on the background during gameplay. This reduces the  amount of pipelines that need to be created significantly.- **Pipeline precompilation**: By using ubershaders, the engine can precompile  pipelines ahead of time in multiple places such as when meshes are loaded or  when nodes are added to the scene. By being part of the resource loading  process, pipelines can even be precompiled in multiple background threads if  possible during loading screens or even gameplay.Starting in Godot 4.4, Godot will detect which pipelines are needed andprecompile them at load-time. This detection system is mostly automatic, but itrelies on the RenderingServer seeing evidence of all shaders, meshes, orrendering features at load-time. For example, if you load a mesh and shaderwhile the game is running, the pipeline for that mesh/shader combination won'tbe compiled until the mesh/shader is loaded. Similarly, things like enablingMSAA, or instancing a VoxelGI node while the game is running will triggerpipeline recompilations.Pipeline precompilation monitors--------------------------------.. UPDATE: Future versions mentioned.Compiling pipelines ahead of time is the main mechanism Godot uses to mitigateshader stutters, but it's not a perfect solution. Being aware of the situationsthat can lead to pipeline stutters can be very helpful, and the workarounds arepretty straightforward compared to previous versions. These workarounds may beless necessary over time with future versions of Godot as more detectiontechniques are implemented.The Godot debugger offers monitors for tracking the amount of pipelines createdby the game and the step that triggered their compilation. You can keep an eyeon these monitors as the game runs to identify potential sources of shaderstutters without having to wipe your driver cache every time you wish to test.Sudden increases of these values outside of loading screens can show up ashitches during gameplay the first time someone plays the game on their system.**It is recommended you take a look at these monitors to identify possiblesources of stutter for your players**, as you might be unable to experience themyourself without deleting your driver cache or testing on a weaker system... figure:: img/pipeline_compilations_monitors.webp   :align: center   :alt: Screenshot of the Godot pipeline compilations monitor   Pipeline compilations of one of the demo projects... note:: We can see the pipelines compiled during gameplay and          verify which steps could possibly cause stuttters. Note          that these values will only increase and never go down,          as deleted pipelines are not tracked by these monitors          and pipelines may be erased and recreated during gameplay.- **Canvas**: Compiled when drawing a 2D node. The engine does not currently  feature precompilation for 2D elements and stutters will show up when the  2D node is drawn for the first time.- **Mesh**: Compiled as part of loading a 3D mesh and identifying what pipelines  can be precompiled from its properties. These can lead to stutters if a mesh  is loaded during gameplay, but they can be mitigated if the mesh is loaded by  using a background thread. **Modifiers that are part of nodes such as material  overrides can't be compiled on this step**.- **Surface**: Compiled when a frame is about to be drawn and 3D objects were  instanced on the scene tree for the first time. This can also include  compilation for nodes that aren't even visible on the scene tree. The stutter  will occur only on the first frame the node is added to the scene, which won't  result in an obvious stutter if it happens right after a loading screen.- **Draw**: Compiled on demand when a 3D object needs to be drawn and an  ubershader was not precompiled ahead of time. The engine is unable to  precompile this pipeline due to triggering a case that hasn't been covered  yet or a modification that was done to the engine's code. Leads to stutters  during gameplay. This is identical to Godot versions before 4.4. If you  see compilations here, please  `let the developers know <https://github.com/godotengine/godot/issues>`  as this should never happen with the Ubershader system.  Make sure to attach a minimal reproduction project when doing so.- **Specialization**: Compiled in the background during gameplay to optimize the  framerate. Unable to cause stutters, but may result in reduced framerates if  there are many happening per frame.Pipeline precompilation features--------------------------------Godot offers a lot of rendering features that are not necessarily used by everygame. Unfortunately, pipeline precompilation can't know ahead of time if aparticular feature is used by a project. Some of these features can only bedetected when a user adds a node to the scene or toggles a particular setting inthe project or the environment. The pipeline precompilation system will keeptrack of these features as they're encountered for the first time and enableprecompilation of them for any meshes or surfaces that are created afterwards.If your game makes use of these features, **make sure to have a scene that usesthem as early as possible** before loading the majority of the assets. Thisscene can be very simple and will do the job as long as it uses the features thegame plans to use. It can even be rendered off-screen for at least one frame ifnecessary, e.g. by covering it with a :ref:`class_ColorRect` node orusing a :ref:`class_SubViewport` located outside the window bounds.You should also keep in mind that changing any of these features during gameplaywill result in immediate stutters. Make sure to only change these features fromconfiguration screens if necessary and insert loading screens and messages whenthe changes are applied.- **MSAA Level**: Enabled when the level of 3D MSAA is changed on the project  settings. Unfortunately, different MSAA levels being used on different  viewports will lead to stutters as the engine only keeps track of one level at  a time to perform precompilation.- **Reflection Probes**: Enabled when a ReflectionProbe node is placed on the  scene.- **Separate Specular**: Enabled when using effects like sub-surface scattering  or a compositor effect that relies on sampling the specularity directly off  the screen.- **Motion Vectors**: Enabled when using effects such as TAA, FSR2 or a  compositor effect that requires motion vectors (such as motion blur).- **Normal and Roughness**: Enabled when using SDFGI, VoxelGI, screen-space  reflections, SSAO, SSIL, or using the ``normal_roughness_buffer`` in a custom  shader or :ref:`class_CompositorEffect`.- **Lightmaps**: Enabled when a LightmapGI node is placed on the scene and a  node uses a baked lightmap.- **VoxelGI**: Enabled when a VoxelGI node is placed on the scene.- **SDFGI**: Enabled when the WorldEnvironment enables SDFGI.- **Multiview**: Enabled for XR projects.- **16/32-bit Shadows**: Enabled when the configuration of the depth precision  of shadowmaps is changed on the project settings.- **Omni Shadow Dual Paraboloid**: Enabled when an omni light casts shadows and  uses the dual paraboloid mode.- **Omni Shadow Cubemap**: Enabled when an omni light casts shadows and uses the  cubemap mode (which is the default).If you witness stutters during gameplay and the monitors report a suddenincrease in compilations during the **Surface** step, it is very likely afeature was not enabled ahead of time. Ensuring that this effect is enabledwhile loading your game will likely mitigate the issue.Pipeline precompilation instancing----------------------------------One common source of stutters in games is the fact that some effects are onlyinstanced on the scene because of interactions that only happen during gameplay.For example, if you have a particle effect that is only added to the scenethrough a script when a player does an action. Even if the scene is preloaded,the engine might be unable to precompile the pipelines until the effect is addedto the scene at least once.Luckily, it's possible for Godot 4.4 and later toprecompile these pipelines as long as the scene is instantiated at least once onthe scene, even if it's completely invisible or outside of the camera's view... figure:: img/pipeline_compilations_hidden_node.webp   :align: center   :alt: Screenshot of an example of a hidden Node for an effect   Hidden bullet node attached to the player in one of the demo projects. This   helps the engine precompile the effect's pipelines ahead of time.If you're aware of any effects that are added to the scene dynamically duringgameplay and are seeing sudden increases on the compilations monitor when theseeffects show up, a workaround is to attach a hidden version of the effectsomewhere that is guaranteed to show up.For example, if the player character is able to cause some sort of explosion,you can attach the effect as a child of the player as an invisible node. Makesure to disable the script attached to the hidden node or to hide any othernodes that could cause issues, which can be done by enabling **EditableChildren** on the node... _doc_pipeline_compilations_shader_baker:Shader baker------------Since Godot 4.5, you can choose to bake shaders on export to improve initialstartup time. This will generally not resolve existing stutters, but it willreduce the time it takes to load the game for the first time. This is especiallythe case when using Direct3D 12 or Metal, which have significantly slower initialshader compilation times than Vulkan due to the conversion step required.Godot's own shaders use GLSL and SPIR-V, but Direct3D 12 and Metal usedifferent formats... note::    The shader baker can only bake the source into the intermediate format    (SPIR-V for Vulkan, DXIL for Direct3D 12, MIL for Metal). It cannot bake    the intermediate format into the final pipeline, as this is    dependent on the GPU driver and the hardware.    The shader baker is not a replacement for pipeline precompilation,    but it aims to complement it.When enabled, the shader baker will bundle compiled shader code into the PCK,which results in the shader compilation step being skipped entirely.The downside is that exporting will take slightly longer. The PCK filewill be larger by a few megabytes.The shader baker is disabled by default, but you can enable it in eachexport preset in the Export dialog by ticking the :ui:`Shader Baker > Enabled`export option.Note that shader baking will only be able to export shaders for drivers supportedby the platform the editor is currently running on:- The editor running on Windows can export shaders for Vulkan and Direct3D 12.- The editor running on macOS can export shaders for Vulkan and Metal.- The editor running on Linux can export shaders for Vulkan only.- The editor running on Android can export shaders for Vulkan only.The shader baker will only export shaders that match the``rendering/rendering_device/driver`` project setting for the target platform... note::    The shader baker is only supported for the Forward+ and Mobile renderers.    It will have no effect if the project uses the Compatibility renderer,    or for users who make use of the Compatibility fallback due to their    hardware not supporting the Forward+ or Mobile renderer.    This also means the shader baker is not supported on the web platform,    as the web platform only supports the Compatibility renderer.
 |