Deferred Lighting Rendering Path Details
This page describes details of Deferred Lighting rendering path. For a technical overview of what Deferred Lighting is, see Deferred Lighting Approaches article.
Deferred Lighting is rendering path with the most lighting and shadow fidelity:
- There's no limit how many lights can affect any object.
- All lights are evaluated per-pixel. Which means that they all interact properly with normal maps etc.
- All lights can have Cookies.
- All lights can have Shadows.
Deferred Lighting's advantages:
- Lighting cost is proportional to light size on screen. Does not matter how many objects it shines on. Small lights = cheap!
- Consistency. All lighting for all lights is computed per-pixel; there are no lighting computations that break down on large triangles etc.
- No real anti-aliasing support.
- Deferred Lighting can't handle semi-transparent objects. Those are rendered using Forward Rendering.
- Limited lighting model support (Blinn-Phong). All lighting is computed the same way; you can't have drastically different lighting models on different objects.
- No support for "receive shadows" flag and limited support light Culling Masks.
Requirements for Deferred Lighting
- Requires Unity Pro.
- Graphics card with Shader Model 3.0 (or later), support for Depth render textures and two-sided stencil buffer. Most graphics cards made after 2004 support it: GeForce FX and later, Radeon X1300 and later, Intel 965 / GMA X3100 and later.
- Currently does not work on mobile platforms.
Performance Considerations
Cost of realtime lights in Deferred Lighting is proportional to number of pixels the light shines on; and not dependent on scene complexity. So small point or spot lights are very cheap to render. Point or spot lights that are fully or partially occluded by some scene objects get their pixels skipped on the GPU, so they are even cheaper.
Of course, lights with shadows are much more expensive than lights without shadows. In Deferred Lighting, shadow casters still need to be rendered once or more for each shadow-casting light. And the lighting shader that applies shadows is also more expensive than one without shadows.
Implementation Details
When Deferred Lighting is used, rendering process in Unity happens like this:
- Base Pass: objects are rendered, producing screen-space buffers with depth, normals, and specular power.
- Lighting pass: lighting is computed using the previous buffers. Lighting is computed into another screen-space buffer.
- Final pass: objects are rendered again. They fetch computed lighting, combine it with color textures and add any ambient/emissive lighting.
Objects with shaders that can't handle Deferred Lighting are rendered after this process is done, using RenderTech-ForwardRendering path.
Base Pass
Base pass renders each object once. View space normals and specular power are rendered into single ARGB32 Render Texture (normals in RGB channels, specular power in A). If platform & hardware supports reading Z buffer as a texture, then depth is not explicitly rendered. If Z buffer can't be accessed as a texture, then depth is rendered in additional rendering pass, using shader replacement.
Result of the base pass is Z buffer filled with scene contents and Render Texture with normals & specular power.
Lighting Pass
Lighting pass computes lighting based on depth, normals and specular power. Lighting is computed in screen space, so it's independent of scene complexity. Lighting buffer is single ARGB32 Render Texture, with diffuse lighting in RGB channels and monochrome specular lighting in A channel. Lighting values are encoded using logarithmic encoding to provide extended dynamic range than usually possible with ARGB32 texture.
Lighting model is fixed to Blinn-Phong.
Point and Spot lights that do not cross camera's near plane are rendered as 3D shapes, with Z buffer test against scene enabled. This makes partially or fully occluded Point and Spot lights very cheap to render. Directional lights and Point/Spot lights that cross the near plane are rendered as fullscreen quads.
If a light has shadows enabled, they are rendered and applies in this pass as well. Note that shadows are not "free"; shadow casters need to be rendered and a more complex light shader needs to be applied.
Final Pass
Final pass produces final rendered image. Here all objects are rendered again; with shaders that fetch the lighting, combine it with textures and add any emissive lighting.
Lightmaps are also applied in the final pass. Close to the camera, realtime lighting is used, and only baked indirect lighting is added. This crossfades into fully baked lighting further away from the camera.
Page last updated: 2010-11-02