pipeline_compilations.rst 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. .. _doc_pipeline_compilations:
  2. Reducing stutter from shader (pipeline) compilations
  3. ====================================================
  4. Pipeline compilation, also commonly known as shader compilation, is an expensive
  5. operation required by the engine to be able to draw any kind of content with the
  6. GPU.
  7. .. figure:: img/pipeline_compilations_shader_compilation_diagram.webp
  8. :align: center
  9. :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.
  10. Shaders and materials in Godot go through several steps before they can be run
  11. by the GPU.
  12. In more precise terms, *shader compilation* involves the translation of the GLSL
  13. code that Godot generates into an intermediate format that can be shared across
  14. systems (such as SPIR-V when using Vulkan). However, this format can't be used
  15. by the GPU directly.
  16. *Pipeline compilation* is the step where the GPU driver converts
  17. the intermediate shader format (the result from shader compilation) to something
  18. the GPU can actually use for rendering. Drivers usually keep a cache of
  19. pipelines stored somewhere in the system to avoid repeating the process every
  20. time a game is run. This cache is usually deleted when the driver is updated.
  21. Pipelines contain more information than just the shader code, which means that
  22. for each shader, there can be dozens of pipelines or more! This makes it
  23. difficult for an engine to compile them ahead of time, both because it would be
  24. very slow, and because it would take up a lot of memory. On top of that, this
  25. step can only be performed on the user's system and it is very tough to share
  26. the result between users unless they have the exact same hardware and driver
  27. version.
  28. Before Godot 4.4, there was no solution to pipeline compilation other than
  29. generating them when an object shows up inside the camera's view, leading to the
  30. infamous *shader stutter* or hitches that only occur during the first
  31. playthrough. **With Godot 4.4, new mechanisms have been introduced to mitigate
  32. stutters from pipeline compilation.**
  33. - **Ubershaders**: Godot makes use of specialization constants, a feature that
  34. allows the driver to optimize a pipeline's code around a set of parameters
  35. such as lighting, shadow quality, etc. Specialization constants are used to
  36. optimize a shader by limiting unnecessary features. Changing a specialization
  37. constant requires recompiling the pipeline. Ubershaders are a special version
  38. of the shader that are able to change these constants while rendering, which
  39. means Godot can precompile just one pipeline ahead of time and compile the
  40. more optimized versions on the background during gameplay. This reduces the
  41. amount of pipelines that need to be created significantly.
  42. - **Pipeline precompilation**: By using ubershaders, the engine can precompile
  43. pipelines ahead of time in multiple places such as when meshes are loaded or
  44. when nodes are added to the scene. By being part of the resource loading
  45. process, pipelines can even be precompiled in multiple background threads if
  46. possible during loading screens or even gameplay.
  47. Starting in Godot 4.4, Godot will detect which pipelines are needed and
  48. precompile them at load-time. This detection system is mostly automatic, but it
  49. relies on the RenderingServer seeing evidence of all shaders, meshes, or
  50. rendering features at load-time. For example, if you load a mesh and shader
  51. while the game is running, the pipeline for that mesh/shader combination won't
  52. be compiled until the mesh/shader is loaded. Similarly, things like enabling
  53. MSAA, or instancing a VoxelGI node while the game is running will trigger
  54. pipeline recompilations.
  55. Pipeline precompilation monitors
  56. --------------------------------
  57. .. UPDATE: Future versions mentioned.
  58. Compiling pipelines ahead of time is the main mechanism Godot uses to mitigate
  59. shader stutters, but it's not a perfect solution. Being aware of the situations
  60. that can lead to pipeline stutters can be very helpful, and the workarounds are
  61. pretty straightforward compared to previous versions. These workarounds may be
  62. less necessary over time with future versions of Godot as more detection
  63. techniques are implemented.
  64. The Godot debugger offers monitors for tracking the amount of pipelines created
  65. by the game and the step that triggered their compilation. You can keep an eye
  66. on these monitors as the game runs to identify potential sources of shader
  67. stutters without having to wipe your driver cache every time you wish to test.
  68. Sudden increases of these values outside of loading screens can show up as
  69. hitches during gameplay the first time someone plays the game on their system.
  70. **It is recommended you take a look at these monitors to identify possible
  71. sources of stutter for your players**, as you might be unable to experience them
  72. yourself without deleting your driver cache or testing on a weaker system.
  73. .. figure:: img/pipeline_compilations_monitors.webp
  74. :align: center
  75. :alt: Screenshot of the Godot pipeline compilations monitor
  76. Pipeline compilations of one of the demo projects.
  77. .. note:: We can see the pipelines compiled during gameplay and
  78. verify which steps could possibly cause stuttters. Note
  79. that these values will only increase and never go down,
  80. as deleted pipelines are not tracked by these monitors
  81. and pipelines may be erased and recreated during gameplay.
  82. - **Canvas**: Compiled when drawing a 2D node. The engine does not currently
  83. feature precompilation for 2D elements and stutters will show up when the
  84. 2D node is drawn for the first time.
  85. - **Mesh**: Compiled as part of loading a 3D mesh and identifying what pipelines
  86. can be precompiled from its properties. These can lead to stutters if a mesh
  87. is loaded during gameplay, but they can be mitigated if the mesh is loaded by
  88. using a background thread. **Modifiers that are part of nodes such as material
  89. overrides can't be compiled on this step**.
  90. - **Surface**: Compiled when a frame is about to be drawn and 3D objects were
  91. instanced on the scene tree for the first time. This can also include
  92. compilation for nodes that aren't even visible on the scene tree. The stutter
  93. will occur only on the first frame the node is added to the scene, which won't
  94. result in an obvious stutter if it happens right after a loading screen.
  95. - **Draw**: Compiled on demand when a 3D object needs to be drawn and an
  96. ubershader was not precompiled ahead of time. The engine is unable to
  97. precompile this pipeline due to triggering a case that hasn't been covered
  98. yet or a modification that was done to the engine's code. Leads to stutters
  99. during gameplay. This is identical to Godot versions before 4.4. If you
  100. see compilations here, please
  101. `let the developers know <https://github.com/godotengine/godot/issues>`
  102. as this should never happen with the Ubershader system.
  103. Make sure to attach a minimal reproduction project when doing so.
  104. - **Specialization**: Compiled in the background during gameplay to optimize the
  105. framerate. Unable to cause stutters, but may result in reduced framerates if
  106. there are many happening per frame.
  107. Pipeline precompilation features
  108. --------------------------------
  109. Godot offers a lot of rendering features that are not necessarily used by every
  110. game. Unfortunately, pipeline precompilation can't know ahead of time if a
  111. particular feature is used by a project. Some of these features can only be
  112. detected when a user adds a node to the scene or toggles a particular setting in
  113. the project or the environment. The pipeline precompilation system will keep
  114. track of these features as they're encountered for the first time and enable
  115. precompilation of them for any meshes or surfaces that are created afterwards.
  116. If your game makes use of these features, **make sure to have an scene that uses
  117. them as early as possible** before loading the majority of the assets. This
  118. scene can be very simple and will do the job as long as it uses the features the
  119. game plans to use. It can even be rendered off-screen for at least one frame if
  120. necessary, e.g. by covering it with a :ref:`class_ColorRect` node or
  121. using a :ref:`class_SubViewport` located outside the window bounds.
  122. You should also keep in mind that changing any of these features during gameplay
  123. will result in immediate stutters. Make sure to only change these features from
  124. configuration screens if necessary and insert loading screens and messages when
  125. the changes are applied.
  126. - **MSAA Level**: Enabled when the level of 3D MSAA is changed on the project
  127. settings. Unfortunately, different MSAA levels being used on different
  128. viewports will lead to stutters as the engine only keeps track of one level at
  129. a time to perform precompilation.
  130. - **Reflection Probes**: Enabled when a ReflectionProbe node is placed on the
  131. scene.
  132. - **Separate Specular**: Enabled when using effects like sub-surface scattering
  133. or a compositor effect that relies on sampling the specularity directly off
  134. the screen.
  135. - **Motion Vectors**: Enabled when using effects such as TAA, FSR2 or a
  136. compositor effect that requires motion vectors (such as motion blur).
  137. - **Normal and Roughness**: Enabled when using SDFGI, VoxelGI, screen-space
  138. reflections, SSAO, SSIL, or using the ``normal_roughness_buffer`` in a custom
  139. shader or :ref:`class_CompositorEffect`.
  140. - **Lightmaps**: Enabled when a LightmapGI node is placed on the scene and a
  141. node uses a baked lightmap.
  142. - **VoxelGI**: Enabled when a VoxelGI node is placed on the scene.
  143. - **SDFGI**: Enabled when the WorldEnvironment enables SDFGI.
  144. - **Multiview**: Enabled for XR projects.
  145. - **16/32-bit Shadows**: Enabled when the configuration of the depth precision
  146. of shadowmaps is changed on the project settings.
  147. - **Omni Shadow Dual Paraboloid**: Enabled when an omni light casts shadows and
  148. uses the dual paraboloid mode.
  149. - **Omni Shadow Cubemap**: Enabled when an omni light casts shadows and uses the
  150. cubemap mode (which is the default).
  151. If you witness stutters during gameplay and the monitors report a sudden
  152. increase in compilations during the **Surface** step, it is very likely a
  153. feature was not enabled ahead of time. Ensuring that this effect is enabled
  154. while loading your game will likely mitigate the issue.
  155. Pipeline precompilation instancing
  156. ----------------------------------
  157. One common source of stutters in games is the fact that some effects are only
  158. instanced on the scene because of interactions that only happen during gameplay.
  159. For example, if you have a particle effect that is only added to the scene
  160. through a script when a player does an action. Even if the scene is preloaded,
  161. the engine might be unable to precompile the pipelines until the effect is added
  162. to the scene at least once.
  163. Luckily, it's possible for Godot 4.4 and later to
  164. precompile these pipelines as long as the scene is instantiated at least once on
  165. the scene, even if it's completely invisible or outside of the camera's view.
  166. .. figure:: img/pipeline_compilations_hidden_node.webp
  167. :align: center
  168. :alt: Screenshot of an example of a hidden Node for an effect
  169. Hidden bullet node attached to the player in one of the demo projects. This
  170. helps the engine precompile the effect's pipelines ahead of time.
  171. If you're aware of any effects that are added to the scene dynamically during
  172. gameplay and are seeing sudden increases on the compilations monitor when these
  173. effects show up, a workaround is to attach a hidden version of the effect
  174. somewhere that is guaranteed to show up.
  175. For example, if the player character is able to cause some sort of explosion,
  176. you can attach the effect as a child of the player as an invisible node. Make
  177. sure to disable the script attached to the hidden node or to hide any other
  178. nodes that could cause issues, which can be done by enabling **Editable
  179. Children** on the node.