In Unreal Engine 5, we have the choice between two primary rendering backends: Forward Shading and Deferred Shading.
While Forward Shading is often viewed as the "traditional" or "old" way of rendering, and Deferred Shading as the modern standard, the choice isn't just about age—it's about how the engine handles the relationship between geometry and lighting.
The Core Difference
-
Forward Shading: Each object is drawn to the screen one by one. For every object, the shader calculates the material and all the lights affecting it in a single pass.
- The Bottleneck: If you have 50 lights and 10 objects, the GPU has to do a massive amount of redundant calculation.
-
Deferred Shading: This "defers" the lighting until later. First, the engine renders the scene geometry into a set of buffers (the GBuffer) containing data like base color, roughness, and normals. Only after the GBuffer is built does the engine calculate lighting as a separate 2D screen-space pass.
Why go Deferred?
The primary reason Unreal uses Deferred Shading by default is lighting complexity.
- Light Density: You can have hundreds of dynamic lights because the cost of a light is proportional to the number of pixels it covers, not the number of objects it hits.
- Advanced Features: Features like Lumen, Screen Space Reflections (SSR), and Decals rely heavily on the GBuffer data provided by the deferred pipeline.
Why go Forward?
If Deferred is "better" for modern features, why does Forward still exist?
- MSAA Support: As mentioned on the homepage, Deferred Shading is incompatible with MSAA. If your project requires the crispness of Multisample Anti-Aliasing (common in VR), Forward is your only real choice.
- Lower Base Cost: For projects with simple lighting, Forward can be significantly faster because it avoids the heavy memory overhead of writing to and reading from the GBuffer.
Common Side Effects With Both
Deferred Shading
-
Edge Artifacts & Smearing: Because you lose access to hardware MSAA, you are forced to rely on Temporal Anti-Aliasing (TAA/TSR). If the render resolution is too low or the jitter sequence is poorly tuned, you get a "smearing" effect or ghosting on moving objects.
-
High Memory Bandwidth: The GBuffer is "fat." Writing out all that data (normals, roughness, depth) to multiple textures every frame puts a high floor on your GPU memory bandwidth requirements.
-
Translucency Complexity: Since lighting is deferred until after the opaque geometry is drawn, translucent objects (glass, water, particles) don't naturally "fit" in the GBuffer. They usually require a separate forward-rendered pass, which can lead to lighting inconsistencies.
Forward Shading
-
The "Shader Permutation" Explosion: Since every light and material combination has to be calculated in a single pass, the number of shader permutations can skyrocket. This leads to longer compile times and larger executable sizes.
-
Material Limitations: You lose access to some GBuffer-specific features. Certain screen-space effects or complex layering that rely on having the scene’s depth and normals pre-calculated are either impossible or prohibitively expensive.
-
Light Limits: You are typically capped on the number of local lights that can affect a single mesh (often 8 or fewer). If you exceed this, you’ll see lights "popping" in and out as the engine tries to prioritize which ones to render.