internal_rendering_architecture.rst 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. .. _doc_internal_rendering_architecture:
  2. Internal rendering architecture
  3. ===============================
  4. This page is a high-level overview of Godot 4's internal renderer design.
  5. It does not apply to previous Godot versions.
  6. The goal of this page is to document design decisions taken to best suit
  7. `Godot's design philosophy <https://contributing.godotengine.org/en/latest/engine/guidelines/best_practices.html>`__,
  8. while providing a starting point for new rendering contributors.
  9. If you have questions about rendering internals not answered here, feel free to
  10. ask in the ``#rendering`` channel of the
  11. `Godot Contributors Chat <https://chat.godotengine.org/channel/rendering>`__.
  12. .. note::
  13. If you have difficulty understanding concepts on this page, it is
  14. recommended to go through an OpenGL tutorial such as
  15. `LearnOpenGL <https://learnopengl.com/>`__.
  16. Modern low-level APIs (Vulkan/Direct3D 12/Metal) require intermediate
  17. knowledge of higher-level APIs (OpenGL/Direct3D 11) to be used
  18. effectively. Thankfully, contributors rarely need to work directly with
  19. low-level APIs. Godot's renderers are built entirely on OpenGL and
  20. RenderingDevice, which is our abstraction over Vulkan/Direct3D 12/Metal.
  21. .. _doc_internal_rendering_architecture_methods:
  22. Rendering methods
  23. -----------------
  24. Forward+
  25. ~~~~~~~~
  26. This is a forward renderer that uses a *clustered* approach to lighting.
  27. Clustered lighting uses a compute shader to group lights into a 3D frustum
  28. aligned grid. Then, at render time, pixels can lookup what lights affect the
  29. grid cell they are in and only run light calculations for lights that might
  30. affect that pixel.
  31. This approach can greatly speed up rendering performance on desktop hardware,
  32. but is substantially less efficient on mobile.
  33. Mobile
  34. ~~~~~~
  35. This is a forward renderer that uses a traditional single-pass approach to lighting.
  36. Internally, it is called **Forward Mobile**.
  37. Intended for mobile platforms, but can also run on desktop platforms. This
  38. rendering method is optimized to perform well on mobile GPUs. Mobile GPUs have a
  39. very different architecture compared to desktop GPUs due to their unique
  40. constraints around battery usage, heat, and overall bandwidth limitations of
  41. reading and writing data. Compute shaders also have very limited support or
  42. aren't supported at all. As a result, the mobile renderer purely uses
  43. raster-based shaders (fragment/vertex).
  44. Unlike desktop GPUs, mobile GPUs perform *tile-based rendering*. Instead of
  45. rendering the whole image as a single unit, the image is divided in smaller
  46. tiles that fit within the faster internal memory of the mobile GPU. Each tile is
  47. rendered and then written out to the destination texture. This all happens
  48. automatically on the graphics driver.
  49. The problem is that this introduces bottlenecks in our traditional approach. For
  50. desktop rendering, we render all opaque geometry, then handle the background,
  51. then transparent geometry, then post-processing. Each pass will need to read the
  52. current result into tile memory, perform its operations and then write it out
  53. again. We then wait for all tiles to be completed before moving on to the next
  54. pass.
  55. The first important change in the mobile renderer is that the mobile renderer
  56. does not use the RGBA16F texture formats that the desktop renderer does.
  57. Instead, it is using an R10G10B10A2 UNORM texture format. This halves the bandwidth
  58. required and has further improvements as mobile hardware often further optimizes
  59. for 32-bit formats. The tradeoff is that the mobile renderer has limited HDR
  60. capabilities due to the reduced precision and maximum values in the color data.
  61. The second important change is the use of sub-passes whenever possible.
  62. Sub-passes allows us to perform the rendering steps end-to-end per tile saving
  63. on the overhead introduced by reading from and writing to the tiles between each
  64. rendering pass. The ability to use sub-passes is limited by the inability to
  65. read neighboring pixels, as we're constrained to working within a single tile.
  66. This limitation of subpasses results in not being able to implement features
  67. such as glow and depth of field efficiently. Similarly, if there is a
  68. requirement to read from the screen texture or depth texture, we must fully
  69. write out the rendering result limiting our ability to use sub-passes. When such
  70. features are enabled, a mix of sub-passes and normal passes are used, and these
  71. features result in a notable performance penalty.
  72. On desktop platforms, the use of sub-passes won't have any impact on
  73. performance. However, this rendering method can still perform better than
  74. Forward+ in simple scenes thanks to its lower complexity and lower
  75. bandwidth usage. This is especially noticeable on low-end GPUs, integrated
  76. graphics or in VR applications.
  77. Given its low-end focus, this rendering method does not provide high-end
  78. rendering features such as SDFGI and :ref:`doc_volumetric_fog`. Several
  79. post-processing effects are also not available.
  80. .. _doc_internal_rendering_architecture_compatibility:
  81. Compatibility
  82. ~~~~~~~~~~~~~
  83. .. note::
  84. This is the only rendering method available when using the OpenGL driver.
  85. This rendering method is not available when using Vulkan, Direct3D 12, or Metal.
  86. This is a traditional (non-clustered) forward renderer. Internally, it is called
  87. **GL Compatibility**. It's intended for old GPUs that don't have Vulkan support,
  88. but still works very efficiently on newer hardware. Specifically, it is optimized
  89. for older and lower-end mobile devices. However, many optimizations carry over
  90. making it a good choice for older and lower-end desktop as well.
  91. Like the Mobile renderer, the Compatibility renderer uses an R10G10B10A2 UNORM
  92. texture for 3D rendering. Unlike the mobile renderer, colors are tonemapped and
  93. stored in sRGB format so there is no HDR support. This avoids the need for a
  94. tonemapping pass and allows us to use the lower bit texture without substantial
  95. banding.
  96. The Compatibility renderer uses a traditional forward single-pass approach to
  97. drawing objects with lights, but it uses a multi-pass approach to draw lights
  98. with shadows. Specifically, in the first pass, it can draw multiple lights
  99. without shadows and up to one DirectionalLight3D with shadows. In each
  100. subsequent pass, it can draw up to one OmniLight3D, one SpotLight3D and one
  101. DirectionalLight3D with shadows. Lights with shadows will affect the scene
  102. differently than lights without shadows, as the lighting is blended in sRGB space
  103. instead of linear space. This difference in lighting will impact how the scene
  104. looks and needs to be kept in mind when designing scenes for the Compatibility
  105. renderer.
  106. Given its low-end focus, this rendering method does not provide high-end
  107. rendering features (even less so compared to Mobile). Most
  108. post-processing effects are not available.
  109. Why not deferred rendering?
  110. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  111. Forward rendering generally provides a better tradeoff for performance versus
  112. flexibility, especially when a clustered approach to lighting is used. While
  113. deferred rendering can be faster in some cases, it's also less flexible and
  114. requires using hacks to be able to use MSAA. Since games with a less realistic
  115. art style can benefit a lot from MSAA, we chose to go with forward rendering for
  116. Godot 4 (like Godot 3).
  117. That said, parts of the forward renderer *are* performed with a deferred approach
  118. to allow for some optimizations when possible. This applies to VoxelGI and SDFGI
  119. in particular.
  120. A clustered deferred renderer may be developed in the future. This renderer
  121. could be used in situations where performance is favored over flexibility.
  122. Rendering drivers
  123. -----------------
  124. Godot 4 supports the following graphics APIs:
  125. Vulkan
  126. ~~~~~~
  127. This is the main driver in Godot 4, with most of the development focus going
  128. towards this driver.
  129. Vulkan 1.0 is required as a baseline, with optional Vulkan 1.1 and 1.2 features
  130. used when available. `volk <https://github.com/zeux/volk>`__ is used as a Vulkan
  131. loader, and
  132. `Vulkan Memory Allocator <https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator>`__
  133. is used for memory management.
  134. Both the Forward+ and Mobile
  135. :ref:`doc_internal_rendering_architecture_methods` are supported when using the
  136. Vulkan driver.
  137. **Vulkan context creation:**
  138. - `drivers/vulkan/vulkan_context.cpp <https://github.com/godotengine/godot/blob/4.2/drivers/vulkan/vulkan_context.cpp>`__
  139. **Direct3D 12 context creation:**
  140. - `drivers/d3d12/d3d12_context.cpp <https://github.com/godotengine/godot/blob/master/drivers/d3d12/d3d12_context.cpp>`__
  141. Direct3D 12
  142. ~~~~~~~~~~~
  143. Like Vulkan, the Direct3D 12 driver targets modern platforms only. It is
  144. designed to target both Windows and Xbox (whereas Vulkan can't be used directly on Xbox).
  145. Both the Forward+ and Mobile :ref:`doc_internal_rendering_architecture_methods` can be
  146. used with Direct3D 12.
  147. :ref:`doc_internal_rendering_architecture_core_shaders` are shared with the
  148. Vulkan renderer. Shaders are transpiled from
  149. :abbr:`SPIR-V (Standard Portable Intermediate Representation)` to
  150. :abbr:`DXIL (DirectX Intermediate Language)` using
  151. Mesa NIR (`more information <https://godotengine.org/article/d3d12-adventures-in-shaderland/>`__).
  152. **This driver is still experimental and only available in Godot 4.3 and later.**
  153. While Direct3D 12 allows supporting Direct3D-exclusive features on Windows 11 such
  154. as windowed optimizations and Auto HDR, Vulkan is still recommended for most projects.
  155. See the `pull request that introduced Direct3D 12 support <https://github.com/godotengine/godot/pull/70315>`__
  156. for more information.
  157. Metal
  158. ~~~~~
  159. Godot provides a native Metal driver that works on all Apple Silicon hardware
  160. (macOS ARM). Compared to using the MoltenVK translation layer, this is
  161. significantly faster, particularly in CPU-bound scenarios.
  162. Both the Forward+ and Mobile :ref:`doc_internal_rendering_architecture_methods` can be
  163. used with Metal.
  164. :ref:`doc_internal_rendering_architecture_core_shaders` are shared with the
  165. Vulkan renderer. Shaders are transpiled from GLSL to :abbr:`MSL (Metal Shading Language)`
  166. using SPIRV-Cross.
  167. Godot also supports Metal rendering via `MoltenVK <https://github.com/KhronosGroup/MoltenVK>`__,
  168. which is used as a fallback when native Metal support is not available (e.g. on x86 macOS).
  169. **This driver is still experimental and only available in Godot 4.4 and later.**
  170. See the `pull request that introduced Metal support <https://github.com/godotengine/godot/pull/88199>`__
  171. for more information.
  172. OpenGL
  173. ~~~~~~
  174. This driver uses OpenGL ES 3.0 and targets legacy and low-end devices that don't
  175. support Vulkan. OpenGL 3.3 Core Profile is used on desktop platforms to run this
  176. driver, as most graphics drivers on desktop don't support OpenGL ES.
  177. WebGL 2.0 is used for web exports.
  178. It is possible to use OpenGL ES 3.0 directly on desktop platforms
  179. by passing the ``--rendering-driver opengl3_es`` command line argument, although this
  180. will only work on graphics drivers that feature native OpenGL ES support (such
  181. as Mesa).
  182. Only the :ref:`doc_internal_rendering_architecture_compatibility` rendering
  183. method can be used with the OpenGL driver.
  184. :ref:`doc_internal_rendering_architecture_core_shaders` are entirely different
  185. from the Vulkan renderer.
  186. Many advanced features are not supported with this driver, as it targets low-end
  187. devices first and foremost.
  188. Summary of rendering drivers/methods
  189. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  190. The following rendering API + rendering method combinations are currently possible:
  191. - Vulkan + Forward+ (optionally through MoltenVK on macOS and iOS)
  192. - Vulkan + Mobile (optionally through MoltenVK on macOS and iOS)
  193. - Direct3D 12 + Forward+
  194. - Direct3D 12 + Mobile
  195. - Metal + Forward+
  196. - Metal + Mobile
  197. - OpenGL + Compatibility (optionally through ANGLE on Windows and macOS)
  198. Each combination has its own limitations and performance characteristics. Make
  199. sure to test your changes on all rendering methods if possible before opening a
  200. pull request.
  201. RenderingDevice abstraction
  202. ---------------------------
  203. .. note::
  204. The OpenGL driver does not use the RenderingDevice abstraction.
  205. To make the complexity of modern low-level graphics APIs more manageable,
  206. Godot uses its own abstraction called RenderingDevice.
  207. This means that when writing code for modern rendering methods, you don't
  208. actually use the Vulkan, Direct3D 12, or Metal APIs directly. While this is still
  209. lower-level than an API like OpenGL, this makes working on the renderer easier,
  210. as RenderingDevice will abstract many API-specific quirks for you. The
  211. RenderingDevice presents a similar level of abstraction as WebGPU.
  212. **Vulkan RenderingDevice implementation:**
  213. - `drivers/vulkan/rendering_device_driver_vulkan.cpp <https://github.com/godotengine/godot/blob/master/drivers/vulkan/rendering_device_driver_vulkan.cpp>`__
  214. **Direct3D 12 RenderingDevice implementation:**
  215. - `drivers/d3d12/rendering_device_driver_d3d12.cpp <https://github.com/godotengine/godot/blob/master/drivers/d3d12/rendering_device_driver_d3d12.cpp>`__
  216. **Metal RenderingDevice implementation:**
  217. - `drivers/metal/rendering_device_driver_metal.mm <https://github.com/godotengine/godot/blob/master/drivers/metal/rendering_device_driver_metal.mm>`__
  218. Core rendering classes architecture
  219. -----------------------------------
  220. This diagram represents the structure of rendering classes in Godot, including the RenderingDevice abstraction:
  221. .. image:: img/rendering_architecture_diagram.webp
  222. `View at full size <https://raw.githubusercontent.com/godotengine/godot-docs/master/engine_details/architecture/img/rendering_architecture_diagram.webp>`__
  223. .. _doc_internal_rendering_architecture_core_shaders:
  224. Core shaders
  225. ------------
  226. While shaders in Godot projects are written using a
  227. :ref:`custom language inspired by GLSL <doc_shading_language>`, core shaders are
  228. written directly in GLSL.
  229. These core shaders are embedded in the editor and export template binaries at
  230. compile-time. To see any changes you've made to those GLSL shaders, you need to
  231. recompile the editor or export template binary.
  232. Some material features such as height mapping, refraction and proximity fade are
  233. not part of core shaders, and are performed in the default BaseMaterial3D using
  234. the Godot shader language instead (not GLSL). This is done by procedurally
  235. generating the required shader code depending on the features enabled in the
  236. material.
  237. By convention, shader files with ``_inc`` in their name are included in other
  238. GLSL files for better code reuse. Standard GLSL preprocessing is used to achieve
  239. this.
  240. .. warning::
  241. Core material shaders will be used by every material in the scene – both
  242. with the default BaseMaterial3D and custom shaders. As a result, these
  243. shaders must be kept as simple as possible to avoid performance issues and
  244. ensure shader compilation doesn't become too slow.
  245. If you use ``if`` branching in a shader, performance may decrease as
  246. :abbr:`VGPR (Vector General-Purpose Register)` usage will increase in the
  247. shader. This happens even if all pixels evaluate to ``true`` or ``false`` in
  248. a given frame.
  249. If you use ``#if`` preprocessor branching, the number of required shader
  250. versions will increase in the scene. In a worst-case scenario, adding a
  251. single boolean ``#define`` can *double* the number of shader versions that
  252. may need to be compiled in a given scene. In some cases, Vulkan
  253. specialization constants can be used as a faster (but more limited)
  254. alternative.
  255. This means there is a high barrier to adding new built-in material features
  256. in Godot, both in the core shaders and BaseMaterial3D. While BaseMaterial3D
  257. can make use of dynamic code generation to only include the shader code if
  258. the feature is enabled, it'll still require generating more shader versions
  259. when these features are used in a project. This can make shader compilation
  260. stutter more noticeable in complex 3D scenes.
  261. See
  262. `The Shader Permutation Problem <https://therealmjp.github.io/posts/shader-permutations-part1/>`__
  263. and
  264. `Branching on a GPU <https://medium.com/@jasonbooth_86226/branching-on-a-gpu-18bfc83694f2>`__
  265. blog posts for more information.
  266. **Core GLSL material shaders:**
  267. - Forward+: `servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl>`__
  268. - Mobile: `servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl>`__
  269. - Compatibility: `drivers/gles3/shaders/scene.glsl <https://github.com/godotengine/godot/blob/4.2/drivers/gles3/shaders/scene.glsl>`__
  270. **Material shader generation:**
  271. - `scene/resources/material.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/material.cpp>`__
  272. **Other GLSL shaders for Forward+ and Mobile rendering methods:**
  273. - `servers/rendering/renderer_rd/shaders/ <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/>`__
  274. - `modules/lightmapper_rd/ <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd>`__
  275. **Other GLSL shaders for the Compatibility rendering method:**
  276. - `drivers/gles3/shaders/ <https://github.com/godotengine/godot/blob/4.2/drivers/gles3/shaders/>`__
  277. 2D and 3D rendering separation
  278. ------------------------------
  279. .. note::
  280. The following is only applicable in the Forward+ and Mobile
  281. rendering methods, not in Compatibility. Multiple Viewports can be used to
  282. emulate this when using the Compatibility renderer, or to perform 2D
  283. resolution scaling.
  284. 2D and 3D are rendered to separate buffers, as 2D rendering in Godot is performed
  285. in :abbr:`LDR (Low Dynamic Range)` sRGB-space while 3D rendering uses
  286. :abbr:`HDR (High Dynamic Range)` linear space.
  287. The color format used for 2D rendering is RGB8 (RGBA8 if the **Transparent**
  288. property on the Viewport is enabled). 3D rendering uses a 24-bit unsigned
  289. normalized integer depth buffer, or 32-bit signed floating-point if a 24-bit
  290. depth buffer is not supported by the hardware. 2D rendering does not use a depth
  291. buffer.
  292. 3D resolution scaling is performed differently depending on whether bilinear or
  293. FSR 1.0 scaling is used. When bilinear scaling is used, no special upscaling
  294. shader is run. Instead, the viewport's texture is stretched and displayed with a
  295. linear sampler (which makes the filtering happen directly on the hardware). This
  296. allows maximizing the performance of bilinear 3D scaling.
  297. The ``configure()`` function in RenderSceneBuffersRD reallocates the 2D/3D
  298. buffers when the resolution or scaling changes.
  299. .. UPDATE: Planned feature. When dynamic resolution scaling is supported,
  300. .. update this paragraph.
  301. Dynamic resolution scaling isn't supported yet, but is planned in a future Godot
  302. release.
  303. **2D and 3D rendering buffer configuration C++ code:**
  304. - `servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp>`__
  305. **FSR 1.0:**
  306. - `servers/rendering/renderer_rd/effects/fsr.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/fsr.cpp>`__
  307. - `thirdparty/amd-fsr/ <https://github.com/godotengine/godot/tree/master/thirdparty/amd-fsr>`__
  308. 2D rendering techniques
  309. -----------------------
  310. 2D light rendering is performed in a single pass to allow for better performance
  311. with large amounts of lights.
  312. All rendering methods feature 2D batching to improve performance, which is
  313. especially noticeable with lots of text on screen.
  314. MSAA can be enabled in 2D to provide "automatic" line and polygon antialiasing,
  315. but FXAA does not affect 2D rendering as it's calculated before 2D rendering
  316. begins. Godot's 2D drawing methods such as the Line2D node or some CanvasItem
  317. ``draw_*()`` methods provide their own way of antialiasing based on triangle
  318. strips and vertex colors, which don't require MSAA to work.
  319. A 2D signed distance field representing LightOccluder2D nodes in the viewport is
  320. automatically generated if a user shader requests it. This can be used for
  321. various effects in custom shaders, such as 2D global illumination. It is also
  322. used to calculate particle collisions in 2D.
  323. **2D SDF generation GLSL shader:**
  324. - `servers/rendering/renderer_rd/shaders/canvas_sdf.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl>`__
  325. 3D rendering techniques
  326. -----------------------
  327. Batching and instancing
  328. ~~~~~~~~~~~~~~~~~~~~~~~
  329. In the Forward+ renderer, Vulkan instancing is used to group rendering of
  330. identical opaque or alpha-tested objects for performance. (Alpha-blended objects
  331. are never instanced.) This is not as fast as static mesh merging, but it still
  332. allows instances to be culled individually.
  333. Light, decal and reflection probe rendering
  334. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  335. .. note::
  336. Decal rendering is currently not available in the Compatibility renderer.
  337. The Forward+ renderer uses clustered lighting. This
  338. allows using as many lights as you want; performance largely depends on screen
  339. coverage. Shadow-less lights can be almost free if they don't occupy much space
  340. on screen.
  341. All rendering methods also support rendering up to 8 directional lights at the
  342. same time (albeit with lower shadow quality when more than one light has shadows
  343. enabled).
  344. The Mobile renderer uses a single-pass lighting approach, with a
  345. limitation of 8 OmniLights + 8 SpotLights affecting each Mesh *resource* (plus a
  346. limitation of 256 OmniLights + 256 SpotLights in the camera view). These limits
  347. are hardcoded and can't be adjusted in the project settings.
  348. The Compatibility renderer uses a hybrid single-pass + multi-pass lighting
  349. approach. Lights without shadows are rendered in a single pass. Lights with
  350. shadows are rendered in multiple passes. This is required for performance
  351. reasons on mobile devices. As a result, performance does not scale well with
  352. many shadow-casting lights. It is recommended to only have a handful of lights
  353. with shadows in the camera frustum at a time and for those lights to be spread
  354. apart so that each object is only touched by 1 or 2 shadowed lights at a time.
  355. The maximum number of lights visible at once can be adjusted in the project
  356. settings.
  357. .. UPDATE: Planned feature. When static and dynamic shadow rendering are
  358. .. separated, update this paragraph.
  359. In all 3 methods, lights without shadows are much cheaper than lights with
  360. shadows. To improve performance, lights are only updated when the light is
  361. modified or when objects in its radius are modified. Godot currently doesn't
  362. separate static shadow rendering from dynamic shadow rendering, but this is
  363. planned in a future release.
  364. Clustering is also used for reflection probes and decal rendering in the
  365. Forward+ renderer.
  366. Shadow mapping
  367. ~~~~~~~~~~~~~~
  368. Both Forward+ and Mobile methods use
  369. :abbr:`PCF (Percentage Closer Filtering)` to filter shadow maps and create a
  370. soft penumbra. Instead of using a fixed PCF pattern, these methods use a vogel
  371. disk pattern which allows for changing the number of samples and smoothly
  372. changing the quality.
  373. Godot also supports percentage-closer soft shadows (PCSS) for more realistic
  374. shadow penumbra rendering. PCSS shadows are limited to the Forward+ renderer
  375. as they're too demanding to be usable in the Mobile renderer.
  376. PCSS also uses a vogel-disk shaped kernel.
  377. Additionally, both shadow-mapping techniques rotate the kernel on a per-pixel
  378. basis to help soften under-sampling artifacts.
  379. The Compatibility renderer supports shadow mapping for DirectionalLight3D,
  380. OmniLight3D, and SpotLight3D lights.
  381. Temporal antialiasing
  382. ~~~~~~~~~~~~~~~~~~~~~
  383. .. note::
  384. Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
  385. Godot uses a custom TAA implementation based on the old TAA implementation from
  386. `Spartan Engine <https://github.com/PanosK92/SpartanEngine>`__.
  387. Temporal antialiasing requires motion vectors to work. If motion vectors
  388. are not correctly generated, ghosting will occur when the camera or objects move.
  389. Motion vectors are generated on the GPU in the main material shader. This is
  390. done by running the vertex shader corresponding to the previous rendered frame
  391. (with the previous camera transform) in addition to the vertex shader for the
  392. current rendered frame, then storing the difference between them in a color buffer.
  393. Alternatively, FSR 2.2 can be used as an upscaling solution that also provides
  394. its own temporal antialiasing algorithm. FSR 2.2 is implemented on top of the
  395. RenderingDevice abstraction as opposed to using AMD's reference code directly.
  396. **TAA resolve:**
  397. - `servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl>`__
  398. **FSR 2.2:**
  399. - `servers/rendering/renderer_rd/effects/fsr2.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/fsr2.cpp>`__
  400. - `servers/rendering/renderer_rd/shaders/effects/fsr2/ <https://github.com/godotengine/godot/tree/master/servers/rendering/renderer_rd/shaders/effects/fsr2>`__
  401. - `thirdparty/amd-fsr2/ <https://github.com/godotengine/godot/tree/master/thirdparty/amd-fsr2>`__
  402. Global illumination
  403. ~~~~~~~~~~~~~~~~~~~
  404. .. note::
  405. VoxelGI and SDFGI are only available in the Forward+ renderer, not the
  406. Mobile or Compatibility renderers.
  407. LightmapGI *baking* is only available in the Forward+ and Mobile renderers,
  408. and can only be performed within the editor (not in an exported
  409. project). LightmapGI *rendering* is supported by the Compatibility renderer.
  410. Godot supports voxel-based GI (VoxelGI), signed distance field GI (SDFGI) and
  411. lightmap baking and rendering (LightmapGI). These techniques can be used
  412. simultaneously if desired.
  413. Lightmap baking happens on the GPU using Vulkan compute shaders. The GPU-based
  414. lightmapper is implemented in the LightmapperRD class, which inherits from the
  415. Lightmapper class. This allows for implementing additional lightmappers, paving
  416. the way for a future port of the CPU-based lightmapper present in Godot 3.x.
  417. This would allow baking lightmaps while using the Compatibility renderer.
  418. **Core GI C++ code:**
  419. - `servers/rendering/renderer_rd/environment/gi.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/environment/gi.cpp>`__
  420. - `scene/3d/voxel_gi.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/voxel_gi.cpp>`__ - VoxelGI node
  421. - `editor/plugins/voxel_gi_editor_plugin.cpp <https://github.com/godotengine/godot/blob/4.2/editor/plugins/voxel_gi_editor_plugin.cpp>`__ - Editor UI for the VoxelGI node
  422. **Core GI GLSL shaders:**
  423. - `servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl>`__
  424. - `servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl>`__ - VoxelGI debug draw mode
  425. - `servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl>`__ - SDFGI Cascades debug draw mode
  426. - `servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl>`__ - SDFGI Probes debug draw mode
  427. - `servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl>`__
  428. - `servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl>`__
  429. - `servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl>`__
  430. **Lightmapper C++ code:**
  431. - `scene/3d/lightmap_gi.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/lightmap_gi.cpp>`__ - LightmapGI node
  432. - `editor/plugins/lightmap_gi_editor_plugin.cpp <https://github.com/godotengine/godot/blob/4.2/editor/plugins/lightmap_gi_editor_plugin.cpp>`__ - Editor UI for the LightmapGI node
  433. - `scene/3d/lightmapper.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/lightmapper.cpp>`__ - Abstract class
  434. - `modules/lightmapper_rd/lightmapper_rd.cpp <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lightmapper_rd.cpp>`__ - GPU-based lightmapper implementation
  435. **Lightmapper GLSL shaders:**
  436. - `modules/lightmapper_rd/lm_raster.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_raster.glsl>`__
  437. - `modules/lightmapper_rd/lm_compute.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_compute.glsl>`__
  438. - `modules/lightmapper_rd/lm_blendseams.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_blendseams.glsl>`__
  439. Depth of field
  440. ~~~~~~~~~~~~~~
  441. .. note::
  442. Only available in the Forward+ and Mobile renderers, not the
  443. Compatibility renderer.
  444. The Forward+ and Mobile renderers use different approaches to DOF rendering, with
  445. different visual results. This is done to best match the performance characteristics
  446. of the target hardware. In Forward+, DOF is performed using a compute shader. In
  447. Mobile, DOF is performed using a fragment shader (raster).
  448. Box, hexagon and circle bokeh shapes are available (from fastest to slowest).
  449. Depth of field can optionally be jittered every frame to improve its appearance
  450. when temporal antialiasing is enabled.
  451. **Depth of field C++ code:**
  452. - `servers/rendering/renderer_rd/effects/bokeh_dof.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/bokeh_dof.cpp>`__
  453. **Depth of field GLSL shader (compute - used for Forward+):**
  454. - `servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl>`__
  455. **Depth of field GLSL shader (raster - used for Mobile):**
  456. - `servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl>`__
  457. Screen-space effects (SSAO, SSIL, SSR, SSS)
  458. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  459. .. note::
  460. Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
  461. The Forward+ renderer supports screen-space ambient occlusion,
  462. screen-space indirect lighting, screen-space reflections and subsurface scattering.
  463. SSAO uses an implementation derived from Intel's
  464. `ASSAO <https://www.intel.com/content/www/us/en/developer/articles/technical/adaptive-screen-space-ambient-occlusion.html>`__
  465. (converted to Vulkan). SSIL is derived from SSAO to provide high-performance
  466. indirect lighting.
  467. When both SSAO and SSIL are enabled, parts of SSAO and SSIL are shared to reduce
  468. the performance impact.
  469. SSAO and SSIL are performed at half resolution by default to improve performance.
  470. SSR is always performed at half resolution to improve performance.
  471. **Screen-space effects C++ code:**
  472. - `servers/rendering/renderer_rd/effects/ss_effects.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/ss_effects.cpp>`__
  473. **Screen-space ambient occlusion GLSL shader:**
  474. - `servers/rendering/renderer_rd/shaders/effects/ssao.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssao.glsl>`__
  475. - `servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl>`__
  476. - `servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl>`__
  477. - `servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl>`__
  478. **Screen-space indirect lighting GLSL shader:**
  479. - `servers/rendering/renderer_rd/shaders/effects/ssil.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssil.glsl>`__
  480. - `servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl>`__
  481. - `servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl>`__
  482. - `servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl>`__
  483. **Screen-space reflections GLSL shader:**
  484. - `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl>`__
  485. - `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl>`__
  486. - `servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl>`__
  487. **Subsurface scattering GLSL:**
  488. - `servers/rendering/renderer_rd/shaders/effects/subsurface_scattering.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/subsurface_scattering.glsl>`__
  489. Sky rendering
  490. ~~~~~~~~~~~~~
  491. .. seealso::
  492. :ref:`doc_sky_shader`
  493. Godot supports using shaders to render the sky background. The radiance map
  494. (which is used to provide ambient light and reflections for PBR materials) is
  495. automatically updated based on the sky shader.
  496. The SkyMaterial resources such as ProceduralSkyMaterial, PhysicalSkyMaterial and
  497. PanoramaSkyMaterial generate a built-in shader for sky rendering. This is
  498. similar to what BaseMaterial3D provides for 3D scene materials.
  499. A detailed technical implementation can be found in the
  500. `Custom sky shaders in Godot 4.0 <https://godotengine.org/article/custom-sky-shaders-godot-4-0>`__
  501. article.
  502. **Sky rendering C++ code:**
  503. - `servers/rendering/renderer_rd/environment/sky.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/environment/sky.cpp>`__ - Sky rendering
  504. - `scene/resources/sky.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/sky.cpp>`__ - Sky resource (not to be confused with sky rendering)
  505. - `scene/resources/sky_material.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/sky_material.cpp>`__ SkyMaterial resources (used in the Sky resource)
  506. **Sky rendering GLSL shader:**
  507. Volumetric fog
  508. ~~~~~~~~~~~~~~
  509. .. note::
  510. Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
  511. .. seealso::
  512. :ref:`doc_fog_shader`
  513. Godot supports a frustum-aligned voxel (froxel) approach to volumetric fog
  514. rendering. As opposed to a post-processing filter, this approach is more
  515. general-purpose as it can work with any light type. Fog can also use shaders for
  516. custom behavior, which allows animating the fog or using a 3D texture to
  517. represent density.
  518. The FogMaterial resource generates a built-in shader for FogVolume nodes. This is
  519. similar to what BaseMaterial3D provides for 3D scene materials.
  520. A detailed technical explanation can be found in the
  521. `Fog Volumes arrive in Godot 4.0 <https://godotengine.org/article/fog-volumes-arrive-in-godot-4>`__
  522. article.
  523. **Volumetric fog C++ code:**
  524. - `servers/rendering/renderer_rd/environment/fog.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/environment/fog.cpp>`__ - General volumetric fog
  525. - `scene/3d/fog_volume.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/fog_volume.cpp>`__ - FogVolume node
  526. - `scene/resources/fog_material.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/fog_material.cpp>`__ - FogMaterial resource (used by FogVolume)
  527. **Volumetric fog GLSL shaders:**
  528. - `servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/volumetric_fog.glsl>`__
  529. - `servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl>`__
  530. Occlusion culling
  531. ~~~~~~~~~~~~~~~~~
  532. While modern GPUs can handle drawing a lot of triangles, the number of draw
  533. calls in complex scenes can still be a bottleneck (even with Vulkan, Direct3D 12,
  534. and Metal).
  535. Godot 4 supports occlusion culling to reduce overdraw (when the depth prepass
  536. is disabled) and reduce vertex throughput.
  537. This is done by rasterizing a low-resolution buffer on the CPU using
  538. `Embree <https://github.com/embree/embree>`__. The buffer's resolution depends
  539. on the number of CPU threads on the system, as this is done in parallel.
  540. This buffer includes occluder shapes that were baked in the editor or created at
  541. runtime.
  542. As complex occluders can introduce a lot of strain on the CPU, baked occluders
  543. can be simplified automatically when generated in the editor.
  544. Godot's occlusion culling doesn't support dynamic occluders yet, but
  545. OccluderInstance3D nodes can still have their visibility toggled or be moved.
  546. However, this will be slow when updating complex occluders this way. Therefore,
  547. updating occluders at runtime is best done only on simple occluder shapes such
  548. as quads or cuboids.
  549. This CPU-based approach has a few advantages over other solutions, such as
  550. portals and rooms or a GPU-based culling solution:
  551. - No manual setup required (but can be tweaked manually for best performance).
  552. - No frame delay, which is problematic in cutscenes during camera cuts or when
  553. the camera moves fast behind a wall.
  554. - Works the same on all rendering drivers and methods, with no unpredictable
  555. behavior depending on the driver or GPU hardware.
  556. Occlusion culling is performed by registering occluder meshes, which is done
  557. using OccluderInstance3D *nodes* (which themselves use Occluder3D *resources*).
  558. RenderingServer then performs occlusion culling by calling Embree in
  559. RendererSceneOcclusionCull.
  560. **Occlusion culling C++ code:**
  561. - `scene/3d/occluder_instance_3d.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/occluder_instance_3d.cpp>`__
  562. - `servers/rendering/renderer_scene_occlusion_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_occlusion_cull.cpp>`__
  563. Visibility range (LOD)
  564. ~~~~~~~~~~~~~~~~~~~~~~
  565. Godot supports manually authored hierarchical level of detail (HLOD), with
  566. distances specified by the user in the inspector.
  567. In RenderingSceneCull, the ``_scene_cull()`` and ``_render_scene()`` functions
  568. are where most of the LOD determination happens. Each viewport can render the
  569. same mesh with different LODs (to allow for split screen rendering to look correct).
  570. **Visibility range C++ code:**
  571. - `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_cull.cpp>`__
  572. Automatic mesh LOD
  573. ~~~~~~~~~~~~~~~~~~
  574. The ImporterMesh class is used for the 3D mesh import workflow in the editor.
  575. Its ``generate_lods()`` function handles generating using the
  576. `meshoptimizer <https://meshoptimizer.org/>`__ library.
  577. LOD mesh generation also generates shadow meshes at the same time. These are
  578. meshes that have their vertices welded regardless of smoothing and materials.
  579. This is used to improve shadow rendering performance by lowering the vertex
  580. throughput required to render shadows.
  581. The RenderingSceneCull class's ``_render_scene()`` function determines which
  582. mesh LOD should be used when rendering. Each viewport can render the
  583. same mesh with different LODs (to allow for split screen rendering to look correct).
  584. The mesh LOD is automatically chosen based on a screen coverage metric. This
  585. takes resolution and camera FOV changes into account without requiring user
  586. intervention. The threshold multiplier can be adjusted in the project settings.
  587. To improve performance, shadow rendering and reflection probe rendering also choose
  588. their own mesh LOD thresholds (which can be different from the main scene rendering).
  589. **Mesh LOD generation on import C++ code:**
  590. - `scene/resources/importer_mesh.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/importer_mesh.cpp>`__
  591. **Mesh LOD determination C++ code:**
  592. - `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_cull.cpp>`__