123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830 |
- .. _doc_internal_rendering_architecture:
- Internal rendering architecture
- ===============================
- This page is a high-level overview of Godot 4's internal renderer design.
- It does not apply to previous Godot versions.
- The goal of this page is to document design decisions taken to best suit
- `Godot's design philosophy <https://contributing.godotengine.org/en/latest/engine/guidelines/best_practices.html>`__,
- while providing a starting point for new rendering contributors.
- If you have questions about rendering internals not answered here, feel free to
- ask in the ``#rendering`` channel of the
- `Godot Contributors Chat <https://chat.godotengine.org/channel/rendering>`__.
- .. note::
- If you have difficulty understanding concepts on this page, it is
- recommended to go through an OpenGL tutorial such as
- `LearnOpenGL <https://learnopengl.com/>`__.
- Modern low-level APIs (Vulkan/Direct3D 12/Metal) require intermediate
- knowledge of higher-level APIs (OpenGL/Direct3D 11) to be used
- effectively. Thankfully, contributors rarely need to work directly with
- low-level APIs. Godot's renderers are built entirely on OpenGL and
- RenderingDevice, which is our abstraction over Vulkan/Direct3D 12/Metal.
- .. _doc_internal_rendering_architecture_methods:
- Rendering methods
- -----------------
- Forward+
- ~~~~~~~~
- This is a forward renderer that uses a *clustered* approach to lighting.
- Clustered lighting uses a compute shader to group lights into a 3D frustum
- aligned grid. Then, at render time, pixels can lookup what lights affect the
- grid cell they are in and only run light calculations for lights that might
- affect that pixel.
- This approach can greatly speed up rendering performance on desktop hardware,
- but is substantially less efficient on mobile.
- Mobile
- ~~~~~~
- This is a forward renderer that uses a traditional single-pass approach to lighting.
- Internally, it is called **Forward Mobile**.
- Intended for mobile platforms, but can also run on desktop platforms. This
- rendering method is optimized to perform well on mobile GPUs. Mobile GPUs have a
- very different architecture compared to desktop GPUs due to their unique
- constraints around battery usage, heat, and overall bandwidth limitations of
- reading and writing data. Compute shaders also have very limited support or
- aren't supported at all. As a result, the mobile renderer purely uses
- raster-based shaders (fragment/vertex).
- Unlike desktop GPUs, mobile GPUs perform *tile-based rendering*. Instead of
- rendering the whole image as a single unit, the image is divided in smaller
- tiles that fit within the faster internal memory of the mobile GPU. Each tile is
- rendered and then written out to the destination texture. This all happens
- automatically on the graphics driver.
- The problem is that this introduces bottlenecks in our traditional approach. For
- desktop rendering, we render all opaque geometry, then handle the background,
- then transparent geometry, then post-processing. Each pass will need to read the
- current result into tile memory, perform its operations and then write it out
- again. We then wait for all tiles to be completed before moving on to the next
- pass.
- The first important change in the mobile renderer is that the mobile renderer
- does not use the RGBA16F texture formats that the desktop renderer does.
- Instead, it is using an R10G10B10A2 UNORM texture format. This halves the bandwidth
- required and has further improvements as mobile hardware often further optimizes
- for 32-bit formats. The tradeoff is that the mobile renderer has limited HDR
- capabilities due to the reduced precision and maximum values in the color data.
- The second important change is the use of sub-passes whenever possible.
- Sub-passes allows us to perform the rendering steps end-to-end per tile saving
- on the overhead introduced by reading from and writing to the tiles between each
- rendering pass. The ability to use sub-passes is limited by the inability to
- read neighboring pixels, as we're constrained to working within a single tile.
- This limitation of subpasses results in not being able to implement features
- such as glow and depth of field efficiently. Similarly, if there is a
- requirement to read from the screen texture or depth texture, we must fully
- write out the rendering result limiting our ability to use sub-passes. When such
- features are enabled, a mix of sub-passes and normal passes are used, and these
- features result in a notable performance penalty.
- On desktop platforms, the use of sub-passes won't have any impact on
- performance. However, this rendering method can still perform better than
- Forward+ in simple scenes thanks to its lower complexity and lower
- bandwidth usage. This is especially noticeable on low-end GPUs, integrated
- graphics or in VR applications.
- Given its low-end focus, this rendering method does not provide high-end
- rendering features such as SDFGI and :ref:`doc_volumetric_fog`. Several
- post-processing effects are also not available.
- .. _doc_internal_rendering_architecture_compatibility:
- Compatibility
- ~~~~~~~~~~~~~
- .. note::
- This is the only rendering method available when using the OpenGL driver.
- This rendering method is not available when using Vulkan, Direct3D 12, or Metal.
- This is a traditional (non-clustered) forward renderer. Internally, it is called
- **GL Compatibility**. It's intended for old GPUs that don't have Vulkan support,
- but still works very efficiently on newer hardware. Specifically, it is optimized
- for older and lower-end mobile devices. However, many optimizations carry over
- making it a good choice for older and lower-end desktop as well.
- Like the Mobile renderer, the Compatibility renderer uses an R10G10B10A2 UNORM
- texture for 3D rendering. Unlike the mobile renderer, colors are tonemapped and
- stored in sRGB format so there is no HDR support. This avoids the need for a
- tonemapping pass and allows us to use the lower bit texture without substantial
- banding.
- The Compatibility renderer uses a traditional forward single-pass approach to
- drawing objects with lights, but it uses a multi-pass approach to draw lights
- with shadows. Specifically, in the first pass, it can draw multiple lights
- without shadows and up to one DirectionalLight3D with shadows. In each
- subsequent pass, it can draw up to one OmniLight3D, one SpotLight3D and one
- DirectionalLight3D with shadows. Lights with shadows will affect the scene
- differently than lights without shadows, as the lighting is blended in sRGB space
- instead of linear space. This difference in lighting will impact how the scene
- looks and needs to be kept in mind when designing scenes for the Compatibility
- renderer.
- Given its low-end focus, this rendering method does not provide high-end
- rendering features (even less so compared to Mobile). Most
- post-processing effects are not available.
- Why not deferred rendering?
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Forward rendering generally provides a better tradeoff for performance versus
- flexibility, especially when a clustered approach to lighting is used. While
- deferred rendering can be faster in some cases, it's also less flexible and
- requires using hacks to be able to use MSAA. Since games with a less realistic
- art style can benefit a lot from MSAA, we chose to go with forward rendering for
- Godot 4 (like Godot 3).
- That said, parts of the forward renderer *are* performed with a deferred approach
- to allow for some optimizations when possible. This applies to VoxelGI and SDFGI
- in particular.
- A clustered deferred renderer may be developed in the future. This renderer
- could be used in situations where performance is favored over flexibility.
- Rendering drivers
- -----------------
- Godot 4 supports the following graphics APIs:
- Vulkan
- ~~~~~~
- This is the main driver in Godot 4, with most of the development focus going
- towards this driver.
- Vulkan 1.0 is required as a baseline, with optional Vulkan 1.1 and 1.2 features
- used when available. `volk <https://github.com/zeux/volk>`__ is used as a Vulkan
- loader, and
- `Vulkan Memory Allocator <https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator>`__
- is used for memory management.
- Both the Forward+ and Mobile
- :ref:`doc_internal_rendering_architecture_methods` are supported when using the
- Vulkan driver.
- **Vulkan context creation:**
- - `drivers/vulkan/vulkan_context.cpp <https://github.com/godotengine/godot/blob/4.2/drivers/vulkan/vulkan_context.cpp>`__
- **Direct3D 12 context creation:**
- - `drivers/d3d12/d3d12_context.cpp <https://github.com/godotengine/godot/blob/master/drivers/d3d12/d3d12_context.cpp>`__
- Direct3D 12
- ~~~~~~~~~~~
- Like Vulkan, the Direct3D 12 driver targets modern platforms only. It is
- designed to target both Windows and Xbox (whereas Vulkan can't be used directly on Xbox).
- Both the Forward+ and Mobile :ref:`doc_internal_rendering_architecture_methods` can be
- used with Direct3D 12.
- :ref:`doc_internal_rendering_architecture_core_shaders` are shared with the
- Vulkan renderer. Shaders are transpiled from
- :abbr:`SPIR-V (Standard Portable Intermediate Representation)` to
- :abbr:`DXIL (DirectX Intermediate Language)` using
- Mesa NIR (`more information <https://godotengine.org/article/d3d12-adventures-in-shaderland/>`__).
- **This driver is still experimental and only available in Godot 4.3 and later.**
- While Direct3D 12 allows supporting Direct3D-exclusive features on Windows 11 such
- as windowed optimizations and Auto HDR, Vulkan is still recommended for most projects.
- See the `pull request that introduced Direct3D 12 support <https://github.com/godotengine/godot/pull/70315>`__
- for more information.
- Metal
- ~~~~~
- Godot provides a native Metal driver that works on all Apple Silicon hardware
- (macOS ARM). Compared to using the MoltenVK translation layer, this is
- significantly faster, particularly in CPU-bound scenarios.
- Both the Forward+ and Mobile :ref:`doc_internal_rendering_architecture_methods` can be
- used with Metal.
- :ref:`doc_internal_rendering_architecture_core_shaders` are shared with the
- Vulkan renderer. Shaders are transpiled from GLSL to :abbr:`MSL (Metal Shading Language)`
- using SPIRV-Cross.
- Godot also supports Metal rendering via `MoltenVK <https://github.com/KhronosGroup/MoltenVK>`__,
- which is used as a fallback when native Metal support is not available (e.g. on x86 macOS).
- **This driver is still experimental and only available in Godot 4.4 and later.**
- See the `pull request that introduced Metal support <https://github.com/godotengine/godot/pull/88199>`__
- for more information.
- OpenGL
- ~~~~~~
- This driver uses OpenGL ES 3.0 and targets legacy and low-end devices that don't
- support Vulkan. OpenGL 3.3 Core Profile is used on desktop platforms to run this
- driver, as most graphics drivers on desktop don't support OpenGL ES.
- WebGL 2.0 is used for web exports.
- It is possible to use OpenGL ES 3.0 directly on desktop platforms
- by passing the ``--rendering-driver opengl3_es`` command line argument, although this
- will only work on graphics drivers that feature native OpenGL ES support (such
- as Mesa).
- Only the :ref:`doc_internal_rendering_architecture_compatibility` rendering
- method can be used with the OpenGL driver.
- :ref:`doc_internal_rendering_architecture_core_shaders` are entirely different
- from the Vulkan renderer.
- Many advanced features are not supported with this driver, as it targets low-end
- devices first and foremost.
- Summary of rendering drivers/methods
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The following rendering API + rendering method combinations are currently possible:
- - Vulkan + Forward+ (optionally through MoltenVK on macOS and iOS)
- - Vulkan + Mobile (optionally through MoltenVK on macOS and iOS)
- - Direct3D 12 + Forward+
- - Direct3D 12 + Mobile
- - Metal + Forward+
- - Metal + Mobile
- - OpenGL + Compatibility (optionally through ANGLE on Windows and macOS)
- Each combination has its own limitations and performance characteristics. Make
- sure to test your changes on all rendering methods if possible before opening a
- pull request.
- RenderingDevice abstraction
- ---------------------------
- .. note::
- The OpenGL driver does not use the RenderingDevice abstraction.
- To make the complexity of modern low-level graphics APIs more manageable,
- Godot uses its own abstraction called RenderingDevice.
- This means that when writing code for modern rendering methods, you don't
- actually use the Vulkan, Direct3D 12, or Metal APIs directly. While this is still
- lower-level than an API like OpenGL, this makes working on the renderer easier,
- as RenderingDevice will abstract many API-specific quirks for you. The
- RenderingDevice presents a similar level of abstraction as WebGPU.
- **Vulkan RenderingDevice implementation:**
- - `drivers/vulkan/rendering_device_driver_vulkan.cpp <https://github.com/godotengine/godot/blob/master/drivers/vulkan/rendering_device_driver_vulkan.cpp>`__
- **Direct3D 12 RenderingDevice implementation:**
- - `drivers/d3d12/rendering_device_driver_d3d12.cpp <https://github.com/godotengine/godot/blob/master/drivers/d3d12/rendering_device_driver_d3d12.cpp>`__
- **Metal RenderingDevice implementation:**
- - `drivers/metal/rendering_device_driver_metal.mm <https://github.com/godotengine/godot/blob/master/drivers/metal/rendering_device_driver_metal.mm>`__
- Core rendering classes architecture
- -----------------------------------
- This diagram represents the structure of rendering classes in Godot, including the RenderingDevice abstraction:
- .. image:: img/rendering_architecture_diagram.webp
- `View at full size <https://raw.githubusercontent.com/godotengine/godot-docs/master/engine_details/architecture/img/rendering_architecture_diagram.webp>`__
- .. _doc_internal_rendering_architecture_core_shaders:
- Core shaders
- ------------
- While shaders in Godot projects are written using a
- :ref:`custom language inspired by GLSL <doc_shading_language>`, core shaders are
- written directly in GLSL.
- These core shaders are embedded in the editor and export template binaries at
- compile-time. To see any changes you've made to those GLSL shaders, you need to
- recompile the editor or export template binary.
- Some material features such as height mapping, refraction and proximity fade are
- not part of core shaders, and are performed in the default BaseMaterial3D using
- the Godot shader language instead (not GLSL). This is done by procedurally
- generating the required shader code depending on the features enabled in the
- material.
- By convention, shader files with ``_inc`` in their name are included in other
- GLSL files for better code reuse. Standard GLSL preprocessing is used to achieve
- this.
- .. warning::
- Core material shaders will be used by every material in the scene – both
- with the default BaseMaterial3D and custom shaders. As a result, these
- shaders must be kept as simple as possible to avoid performance issues and
- ensure shader compilation doesn't become too slow.
- If you use ``if`` branching in a shader, performance may decrease as
- :abbr:`VGPR (Vector General-Purpose Register)` usage will increase in the
- shader. This happens even if all pixels evaluate to ``true`` or ``false`` in
- a given frame.
- If you use ``#if`` preprocessor branching, the number of required shader
- versions will increase in the scene. In a worst-case scenario, adding a
- single boolean ``#define`` can *double* the number of shader versions that
- may need to be compiled in a given scene. In some cases, Vulkan
- specialization constants can be used as a faster (but more limited)
- alternative.
- This means there is a high barrier to adding new built-in material features
- in Godot, both in the core shaders and BaseMaterial3D. While BaseMaterial3D
- can make use of dynamic code generation to only include the shader code if
- the feature is enabled, it'll still require generating more shader versions
- when these features are used in a project. This can make shader compilation
- stutter more noticeable in complex 3D scenes.
- See
- `The Shader Permutation Problem <https://therealmjp.github.io/posts/shader-permutations-part1/>`__
- and
- `Branching on a GPU <https://medium.com/@jasonbooth_86226/branching-on-a-gpu-18bfc83694f2>`__
- blog posts for more information.
- **Core GLSL material shaders:**
- - 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>`__
- - 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>`__
- - Compatibility: `drivers/gles3/shaders/scene.glsl <https://github.com/godotengine/godot/blob/4.2/drivers/gles3/shaders/scene.glsl>`__
- **Material shader generation:**
- - `scene/resources/material.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/material.cpp>`__
- **Other GLSL shaders for Forward+ and Mobile rendering methods:**
- - `servers/rendering/renderer_rd/shaders/ <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/>`__
- - `modules/lightmapper_rd/ <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd>`__
- **Other GLSL shaders for the Compatibility rendering method:**
- - `drivers/gles3/shaders/ <https://github.com/godotengine/godot/blob/4.2/drivers/gles3/shaders/>`__
- 2D and 3D rendering separation
- ------------------------------
- .. note::
- The following is only applicable in the Forward+ and Mobile
- rendering methods, not in Compatibility. Multiple Viewports can be used to
- emulate this when using the Compatibility renderer, or to perform 2D
- resolution scaling.
- 2D and 3D are rendered to separate buffers, as 2D rendering in Godot is performed
- in :abbr:`LDR (Low Dynamic Range)` sRGB-space while 3D rendering uses
- :abbr:`HDR (High Dynamic Range)` linear space.
- The color format used for 2D rendering is RGB8 (RGBA8 if the **Transparent**
- property on the Viewport is enabled). 3D rendering uses a 24-bit unsigned
- normalized integer depth buffer, or 32-bit signed floating-point if a 24-bit
- depth buffer is not supported by the hardware. 2D rendering does not use a depth
- buffer.
- 3D resolution scaling is performed differently depending on whether bilinear or
- FSR 1.0 scaling is used. When bilinear scaling is used, no special upscaling
- shader is run. Instead, the viewport's texture is stretched and displayed with a
- linear sampler (which makes the filtering happen directly on the hardware). This
- allows maximizing the performance of bilinear 3D scaling.
- The ``configure()`` function in RenderSceneBuffersRD reallocates the 2D/3D
- buffers when the resolution or scaling changes.
- .. UPDATE: Planned feature. When dynamic resolution scaling is supported,
- .. update this paragraph.
- Dynamic resolution scaling isn't supported yet, but is planned in a future Godot
- release.
- **2D and 3D rendering buffer configuration C++ code:**
- - `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>`__
- **FSR 1.0:**
- - `servers/rendering/renderer_rd/effects/fsr.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/fsr.cpp>`__
- - `thirdparty/amd-fsr/ <https://github.com/godotengine/godot/tree/master/thirdparty/amd-fsr>`__
- 2D rendering techniques
- -----------------------
- 2D light rendering is performed in a single pass to allow for better performance
- with large amounts of lights.
- All rendering methods feature 2D batching to improve performance, which is
- especially noticeable with lots of text on screen.
- MSAA can be enabled in 2D to provide "automatic" line and polygon antialiasing,
- but FXAA does not affect 2D rendering as it's calculated before 2D rendering
- begins. Godot's 2D drawing methods such as the Line2D node or some CanvasItem
- ``draw_*()`` methods provide their own way of antialiasing based on triangle
- strips and vertex colors, which don't require MSAA to work.
- A 2D signed distance field representing LightOccluder2D nodes in the viewport is
- automatically generated if a user shader requests it. This can be used for
- various effects in custom shaders, such as 2D global illumination. It is also
- used to calculate particle collisions in 2D.
- **2D SDF generation GLSL shader:**
- - `servers/rendering/renderer_rd/shaders/canvas_sdf.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl>`__
- 3D rendering techniques
- -----------------------
- Batching and instancing
- ~~~~~~~~~~~~~~~~~~~~~~~
- In the Forward+ renderer, Vulkan instancing is used to group rendering of
- identical opaque or alpha-tested objects for performance. (Alpha-blended objects
- are never instanced.) This is not as fast as static mesh merging, but it still
- allows instances to be culled individually.
- Light, decal and reflection probe rendering
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- .. note::
- Decal rendering is currently not available in the Compatibility renderer.
- The Forward+ renderer uses clustered lighting. This
- allows using as many lights as you want; performance largely depends on screen
- coverage. Shadow-less lights can be almost free if they don't occupy much space
- on screen.
- All rendering methods also support rendering up to 8 directional lights at the
- same time (albeit with lower shadow quality when more than one light has shadows
- enabled).
- The Mobile renderer uses a single-pass lighting approach, with a
- limitation of 8 OmniLights + 8 SpotLights affecting each Mesh *resource* (plus a
- limitation of 256 OmniLights + 256 SpotLights in the camera view). These limits
- are hardcoded and can't be adjusted in the project settings.
- The Compatibility renderer uses a hybrid single-pass + multi-pass lighting
- approach. Lights without shadows are rendered in a single pass. Lights with
- shadows are rendered in multiple passes. This is required for performance
- reasons on mobile devices. As a result, performance does not scale well with
- many shadow-casting lights. It is recommended to only have a handful of lights
- with shadows in the camera frustum at a time and for those lights to be spread
- apart so that each object is only touched by 1 or 2 shadowed lights at a time.
- The maximum number of lights visible at once can be adjusted in the project
- settings.
- .. UPDATE: Planned feature. When static and dynamic shadow rendering are
- .. separated, update this paragraph.
- In all 3 methods, lights without shadows are much cheaper than lights with
- shadows. To improve performance, lights are only updated when the light is
- modified or when objects in its radius are modified. Godot currently doesn't
- separate static shadow rendering from dynamic shadow rendering, but this is
- planned in a future release.
- Clustering is also used for reflection probes and decal rendering in the
- Forward+ renderer.
- Shadow mapping
- ~~~~~~~~~~~~~~
- Both Forward+ and Mobile methods use
- :abbr:`PCF (Percentage Closer Filtering)` to filter shadow maps and create a
- soft penumbra. Instead of using a fixed PCF pattern, these methods use a vogel
- disk pattern which allows for changing the number of samples and smoothly
- changing the quality.
- Godot also supports percentage-closer soft shadows (PCSS) for more realistic
- shadow penumbra rendering. PCSS shadows are limited to the Forward+ renderer
- as they're too demanding to be usable in the Mobile renderer.
- PCSS also uses a vogel-disk shaped kernel.
- Additionally, both shadow-mapping techniques rotate the kernel on a per-pixel
- basis to help soften under-sampling artifacts.
- The Compatibility renderer supports shadow mapping for DirectionalLight3D,
- OmniLight3D, and SpotLight3D lights.
- Temporal antialiasing
- ~~~~~~~~~~~~~~~~~~~~~
- .. note::
- Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
- Godot uses a custom TAA implementation based on the old TAA implementation from
- `Spartan Engine <https://github.com/PanosK92/SpartanEngine>`__.
- Temporal antialiasing requires motion vectors to work. If motion vectors
- are not correctly generated, ghosting will occur when the camera or objects move.
- Motion vectors are generated on the GPU in the main material shader. This is
- done by running the vertex shader corresponding to the previous rendered frame
- (with the previous camera transform) in addition to the vertex shader for the
- current rendered frame, then storing the difference between them in a color buffer.
- Alternatively, FSR 2.2 can be used as an upscaling solution that also provides
- its own temporal antialiasing algorithm. FSR 2.2 is implemented on top of the
- RenderingDevice abstraction as opposed to using AMD's reference code directly.
- **TAA resolve:**
- - `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>`__
- **FSR 2.2:**
- - `servers/rendering/renderer_rd/effects/fsr2.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/fsr2.cpp>`__
- - `servers/rendering/renderer_rd/shaders/effects/fsr2/ <https://github.com/godotengine/godot/tree/master/servers/rendering/renderer_rd/shaders/effects/fsr2>`__
- - `thirdparty/amd-fsr2/ <https://github.com/godotengine/godot/tree/master/thirdparty/amd-fsr2>`__
- Global illumination
- ~~~~~~~~~~~~~~~~~~~
- .. note::
- VoxelGI and SDFGI are only available in the Forward+ renderer, not the
- Mobile or Compatibility renderers.
- LightmapGI *baking* is only available in the Forward+ and Mobile renderers,
- and can only be performed within the editor (not in an exported
- project). LightmapGI *rendering* is supported by the Compatibility renderer.
- Godot supports voxel-based GI (VoxelGI), signed distance field GI (SDFGI) and
- lightmap baking and rendering (LightmapGI). These techniques can be used
- simultaneously if desired.
- Lightmap baking happens on the GPU using Vulkan compute shaders. The GPU-based
- lightmapper is implemented in the LightmapperRD class, which inherits from the
- Lightmapper class. This allows for implementing additional lightmappers, paving
- the way for a future port of the CPU-based lightmapper present in Godot 3.x.
- This would allow baking lightmaps while using the Compatibility renderer.
- **Core GI C++ code:**
- - `servers/rendering/renderer_rd/environment/gi.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/environment/gi.cpp>`__
- - `scene/3d/voxel_gi.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/voxel_gi.cpp>`__ - VoxelGI node
- - `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
- **Core GI GLSL shaders:**
- - `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>`__
- - `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
- - `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
- - `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
- - `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>`__
- - `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>`__
- - `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>`__
- **Lightmapper C++ code:**
- - `scene/3d/lightmap_gi.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/lightmap_gi.cpp>`__ - LightmapGI node
- - `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
- - `scene/3d/lightmapper.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/lightmapper.cpp>`__ - Abstract class
- - `modules/lightmapper_rd/lightmapper_rd.cpp <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lightmapper_rd.cpp>`__ - GPU-based lightmapper implementation
- **Lightmapper GLSL shaders:**
- - `modules/lightmapper_rd/lm_raster.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_raster.glsl>`__
- - `modules/lightmapper_rd/lm_compute.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_compute.glsl>`__
- - `modules/lightmapper_rd/lm_blendseams.glsl <https://github.com/godotengine/godot/blob/4.2/modules/lightmapper_rd/lm_blendseams.glsl>`__
- Depth of field
- ~~~~~~~~~~~~~~
- .. note::
- Only available in the Forward+ and Mobile renderers, not the
- Compatibility renderer.
- The Forward+ and Mobile renderers use different approaches to DOF rendering, with
- different visual results. This is done to best match the performance characteristics
- of the target hardware. In Forward+, DOF is performed using a compute shader. In
- Mobile, DOF is performed using a fragment shader (raster).
- Box, hexagon and circle bokeh shapes are available (from fastest to slowest).
- Depth of field can optionally be jittered every frame to improve its appearance
- when temporal antialiasing is enabled.
- **Depth of field C++ code:**
- - `servers/rendering/renderer_rd/effects/bokeh_dof.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/bokeh_dof.cpp>`__
- **Depth of field GLSL shader (compute - used for Forward+):**
- - `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>`__
- **Depth of field GLSL shader (raster - used for Mobile):**
- - `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>`__
- Screen-space effects (SSAO, SSIL, SSR, SSS)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- .. note::
- Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
- The Forward+ renderer supports screen-space ambient occlusion,
- screen-space indirect lighting, screen-space reflections and subsurface scattering.
- SSAO uses an implementation derived from Intel's
- `ASSAO <https://www.intel.com/content/www/us/en/developer/articles/technical/adaptive-screen-space-ambient-occlusion.html>`__
- (converted to Vulkan). SSIL is derived from SSAO to provide high-performance
- indirect lighting.
- When both SSAO and SSIL are enabled, parts of SSAO and SSIL are shared to reduce
- the performance impact.
- SSAO and SSIL are performed at half resolution by default to improve performance.
- SSR is always performed at half resolution to improve performance.
- **Screen-space effects C++ code:**
- - `servers/rendering/renderer_rd/effects/ss_effects.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/effects/ss_effects.cpp>`__
- **Screen-space ambient occlusion GLSL shader:**
- - `servers/rendering/renderer_rd/shaders/effects/ssao.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssao.glsl>`__
- - `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>`__
- - `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>`__
- - `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>`__
- **Screen-space indirect lighting GLSL shader:**
- - `servers/rendering/renderer_rd/shaders/effects/ssil.glsl <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/shaders/effects/ssil.glsl>`__
- - `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>`__
- - `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>`__
- - `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>`__
- **Screen-space reflections GLSL shader:**
- - `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>`__
- - `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>`__
- - `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>`__
- **Subsurface scattering GLSL:**
- - `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>`__
- Sky rendering
- ~~~~~~~~~~~~~
- .. seealso::
- :ref:`doc_sky_shader`
- Godot supports using shaders to render the sky background. The radiance map
- (which is used to provide ambient light and reflections for PBR materials) is
- automatically updated based on the sky shader.
- The SkyMaterial resources such as ProceduralSkyMaterial, PhysicalSkyMaterial and
- PanoramaSkyMaterial generate a built-in shader for sky rendering. This is
- similar to what BaseMaterial3D provides for 3D scene materials.
- A detailed technical implementation can be found in the
- `Custom sky shaders in Godot 4.0 <https://godotengine.org/article/custom-sky-shaders-godot-4-0>`__
- article.
- **Sky rendering C++ code:**
- - `servers/rendering/renderer_rd/environment/sky.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_rd/environment/sky.cpp>`__ - Sky rendering
- - `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)
- - `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)
- **Sky rendering GLSL shader:**
- Volumetric fog
- ~~~~~~~~~~~~~~
- .. note::
- Only available in the Forward+ renderer, not the Mobile or Compatibility renderers.
- .. seealso::
- :ref:`doc_fog_shader`
- Godot supports a frustum-aligned voxel (froxel) approach to volumetric fog
- rendering. As opposed to a post-processing filter, this approach is more
- general-purpose as it can work with any light type. Fog can also use shaders for
- custom behavior, which allows animating the fog or using a 3D texture to
- represent density.
- The FogMaterial resource generates a built-in shader for FogVolume nodes. This is
- similar to what BaseMaterial3D provides for 3D scene materials.
- A detailed technical explanation can be found in the
- `Fog Volumes arrive in Godot 4.0 <https://godotengine.org/article/fog-volumes-arrive-in-godot-4>`__
- article.
- **Volumetric fog C++ code:**
- - `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
- - `scene/3d/fog_volume.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/fog_volume.cpp>`__ - FogVolume node
- - `scene/resources/fog_material.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/fog_material.cpp>`__ - FogMaterial resource (used by FogVolume)
- **Volumetric fog GLSL shaders:**
- - `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>`__
- - `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>`__
- Occlusion culling
- ~~~~~~~~~~~~~~~~~
- While modern GPUs can handle drawing a lot of triangles, the number of draw
- calls in complex scenes can still be a bottleneck (even with Vulkan, Direct3D 12,
- and Metal).
- Godot 4 supports occlusion culling to reduce overdraw (when the depth prepass
- is disabled) and reduce vertex throughput.
- This is done by rasterizing a low-resolution buffer on the CPU using
- `Embree <https://github.com/embree/embree>`__. The buffer's resolution depends
- on the number of CPU threads on the system, as this is done in parallel.
- This buffer includes occluder shapes that were baked in the editor or created at
- runtime.
- As complex occluders can introduce a lot of strain on the CPU, baked occluders
- can be simplified automatically when generated in the editor.
- Godot's occlusion culling doesn't support dynamic occluders yet, but
- OccluderInstance3D nodes can still have their visibility toggled or be moved.
- However, this will be slow when updating complex occluders this way. Therefore,
- updating occluders at runtime is best done only on simple occluder shapes such
- as quads or cuboids.
- This CPU-based approach has a few advantages over other solutions, such as
- portals and rooms or a GPU-based culling solution:
- - No manual setup required (but can be tweaked manually for best performance).
- - No frame delay, which is problematic in cutscenes during camera cuts or when
- the camera moves fast behind a wall.
- - Works the same on all rendering drivers and methods, with no unpredictable
- behavior depending on the driver or GPU hardware.
- Occlusion culling is performed by registering occluder meshes, which is done
- using OccluderInstance3D *nodes* (which themselves use Occluder3D *resources*).
- RenderingServer then performs occlusion culling by calling Embree in
- RendererSceneOcclusionCull.
- **Occlusion culling C++ code:**
- - `scene/3d/occluder_instance_3d.cpp <https://github.com/godotengine/godot/blob/4.2/scene/3d/occluder_instance_3d.cpp>`__
- - `servers/rendering/renderer_scene_occlusion_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_occlusion_cull.cpp>`__
- Visibility range (LOD)
- ~~~~~~~~~~~~~~~~~~~~~~
- Godot supports manually authored hierarchical level of detail (HLOD), with
- distances specified by the user in the inspector.
- In RenderingSceneCull, the ``_scene_cull()`` and ``_render_scene()`` functions
- are where most of the LOD determination happens. Each viewport can render the
- same mesh with different LODs (to allow for split screen rendering to look correct).
- **Visibility range C++ code:**
- - `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_cull.cpp>`__
- Automatic mesh LOD
- ~~~~~~~~~~~~~~~~~~
- The ImporterMesh class is used for the 3D mesh import workflow in the editor.
- Its ``generate_lods()`` function handles generating using the
- `meshoptimizer <https://meshoptimizer.org/>`__ library.
- LOD mesh generation also generates shadow meshes at the same time. These are
- meshes that have their vertices welded regardless of smoothing and materials.
- This is used to improve shadow rendering performance by lowering the vertex
- throughput required to render shadows.
- The RenderingSceneCull class's ``_render_scene()`` function determines which
- mesh LOD should be used when rendering. Each viewport can render the
- same mesh with different LODs (to allow for split screen rendering to look correct).
- The mesh LOD is automatically chosen based on a screen coverage metric. This
- takes resolution and camera FOV changes into account without requiring user
- intervention. The threshold multiplier can be adjusted in the project settings.
- To improve performance, shadow rendering and reflection probe rendering also choose
- their own mesh LOD thresholds (which can be different from the main scene rendering).
- **Mesh LOD generation on import C++ code:**
- - `scene/resources/importer_mesh.cpp <https://github.com/godotengine/godot/blob/4.2/scene/resources/importer_mesh.cpp>`__
- **Mesh LOD determination C++ code:**
- - `servers/rendering/renderer_scene_cull.cpp <https://github.com/godotengine/godot/blob/4.2/servers/rendering/renderer_scene_cull.cpp>`__
|