Game Development Reference
// assign lights to 2D tiles
tiles2D = build_2d_tiles();
lightLists2D = assign_lights_to_2d_tiles( tiles2D );
// draw opaque geometry in pre-Z pass and find tiles'
// extents in the Z-direction
depthBuffer = render_preZ_pass();
tileZBounds = reduce_z_bounds( tiles2D, depthBuffer );
// for transparent geometry, prune lights against maximum Z-direction
= prune_lights_max( lightLists2D , tileZBounds );
// for opaque geometry additionally prune lights against
// minimum Z-direction
= prune_lights_min( lightListsTrans , tileZBounds );
// later: rendering
draw( opaque geometry, lightListsOpaque );
draw( trasparent geometry, lightListsTrans );
Listing 4.2. Pseudocode describing the rendering algorithm used to support trans-
parency, as shown in Figure 4.1(b) . We perform the additional optimization where we
first prune lights based on the maximum Z-direction, which gives the light assignment
for transparent geometry. Then, we prune lights in the minimum Z-direction, which
gives us light lists for opaque geometry.
Rendering and shading. No special modifications are required here, other than
using the appropriate set of light lists for opaque and transparent geometries, re-
spectively. First, all opaque geometry should be rendered. Then the transparent
geometry is rendered back to front. 1
Support for MSAA
Supporting MSAA and similar schemes is very simple with tiled forward shading.
We mainly need to ensure that all render targets are created with MSAA enabled.
Additionally, we need to consider all (multi)samples during the optional minimum
or maximum Z-reduction step.
We show the effect of MSAA on render time in Figure 4.4. As we compare to
tiled deferred shading, which does not support transparency, Figure 4.4 includes
transparency. Additionally, we compare memory usage between our forward and
1 In our demo, we sort on a per-object basis, which obviously causes some artifacts when
transparent objects overlap. This is not a limitation in the technique but rather one in our