2.20
Deferred Rendering: Lighting

- 2.20.1. Overview
- 2.20.2. Light Buffer
- 2.20.3. Light Clip Volumes
- 2.20.4. Types

2.20.1
Overview
1
The second step in deferred rendering involves rendering the light contributions of all light sources within a scene to a light buffer. The rendering algorithm requires sampling from a populated geometry buffer.
2.20.2
Light Buffer
1
A light buffer is a render target in which the light contributions of all light sources are summed in preparation for being combined with the surface albedo of a geometry buffer to produce a lit image.
2
A light buffer consists of a 32-bit RGBA diffuse image and a 32-bit RGBA specular image. Currently, the alpha channels of both images are unused and exist solely because OpenGL 3.3 does not provide a color-renderable 24-bit RGB format.
3
The r2 package offers the ability to disable specular lighting entirely if it is not needed, and so light buffer implementations provide the ability to avoid allocating an image for specular contributions if they will not be calculated.
4
In the r2 package, light buffers are instances of R2LightBufferType.
2.20.3
Light Clip Volumes
1
A light clip volume is a means of constraining the contributions of groups of light sources to a provided volume.
2
Because, like most renderers, the r2 package implements so-called local illumination, lights that do not have explicit shadow mapping enabled are able to bleed through solid objects:
2.20.3.3 Local Light Bleed
4
Enabling shadow mapping for every single light source would be prohibitively expensive [3], but for some scenes, acceptable results can be achieved by simply preventing the light source from affecting pixels outside of a given clip volume.
2.20.3.5 Local Light Clipped
6
The technique is implemented using the stencil buffer, using a single light clip volume bit.
2.20.3.7 Algorithm

1. Disable depth writing, and enable depth testing using the standard less-than-or-equal-to depth function is used.
2. For each light clip volume v:
   1. Clear the light clip volume bit in the stencil buffer.
   2. Configure stencil testing such that the stencil test always passes.
   3. Configure stencil writing such that:
      - Only the light clip volume bit can be written.
      - Pixels that fail the depth test will invert the value of the light clip volume bit (GL_INVERT).
      - Pixels that pass the depth test leave the value of the light clip volume bit untouched.
      - Pixels that pass the stencil test leave the value of the light clip volume bit untouched.
   4. Render both the front and back faces of v.
   5. Configure stencil testing such that only those pixels with both the allow bit and light clip volume bit set will be touched.
   6. Render all of the light sources associated with v.

8
The reason the algorithm works can be inferred from the following diagram:
2.20.3.9 Stencil Test Diagram
10
In the diagram, the grey polygons represent the already-rendered depths of the scene geometry [19]. If a point is inside or behind (from the perspective of the observer) one of the polygons, then the depth of the point is considered to be greater than the scene geometry.
11
In the diagram, when rendering the front face of the light volume at point P0, the depth of the light volume face at P0 is less than the current scene depth, and so the depth test succeeds and the light clip volume bit is not touched. When rendering the back face of the light volume at point P1, the depth of the light volume face at P1 is greater than the current scene depth so the depth test fails, and the light clip volume bit is inverted, setting it to true. This means that the scene geometry along that view ray is inside the light clip volume.
12
In the diagram, when rendering the front face of the light volume at point P2, the depth of the light volume face at P2 is greater than the current scene depth, and so the depth test fails and the light clip volume bit is inverted, setting it to true. When rendering the back face of the light volume at point P3, the depth of the light volume face at P3 is greater than the current scene depth, so the depth test fails and the light clip volume bit is inverted again, setting it to false. This means that the scene geometry along that view ray is outside the light clip volume.
13
In the diagram, when rendering the front face of the light volume at point P4, the depth of the light volume face at P4 is less than the current scene depth, and so the depth test succeeds and the light clip volume bit is not touched. When rendering the back face of the light volume at point P5, the depth of the light volume face at P5 is less than the current scene depth, and so the depth test succeeds and the light clip volume bit is not touched. Because the light clip volume bit is false by default and is not modified, this results in the scene geometry along that view ray being considered to be outside the light clip volume.
14
Given the initial depth buffer from an example scene:
2.20.3.15 Depth Buffer
16
The stencil buffer for the initial scene has all of the geometry with the allow bit set:
2.20.3.17 Stencil Buffer (Initial)
18
After rendering a cuboid-shaped light volume that is intended to constrain the contributions of a light source to a single area, all pixels that fell within the clip volume have the light clip volume bit set:
2.20.3.19 Stencil Buffer (Result)
20
Then, after rendering the light contribution of the constrainted light, the light contribution becomes:
2.20.3.21 Light Buffer (Result)
2.20.4
Types
1
In the r2 package, the primary implementation of the deferred light rendering algorithm is the R2LightRenderer type.

[19]
This is slightly misleading because the depth buffer is a simple heightmap and so of course only the nearest faces of each shape would be preserved by the depth buffer. Nevertheless, for the purposes of comprehension, the full shapes are shown.