core idea of the method is to interlace transparent objects with opaque ones in the geometry phase, then perform lighting, and then de-interlace and blend them in the composition phase.
The method itself requires only transparency alpha to be saved in the G-buffer, and no other additional data and no pipeline changes. The general performance hit of the method is about 2.2%, making it attractive for production use.
T
RANSPARENCYTransparency (or translucency or alpha compositing) is the process of combining a partially transparent color with its background.
Rendering transparency (also known as alpha blending) requires two colors, cs (source color) and cd (destination color), and a transparency level a (usually a part of source color) to be composited with the next alpha blend formula:
c0 = caa + cd(−a) or:
c0 = cd + (ca−cd)a
DEFERRED RENDERING
Deferred rendering (also known as deferred shading) is a combination of the conventional forward rendering technique with the advantages of image space techniques [DEERING88].
Deferred rendering is usually performed in four phases.
1. Geometry phase: This is actually the only phase that uses object mesh data; objects, color, position, normal, and additional lighting factors are rendered into render targets.
2. Lighting phase: Lights are applied in screen-space.
3. Composition phase: The color buffer from the geometry phase and lighting from the lighting phase are combined.
4. Post-processing phase: Various effects are applied to create the final image, for example, motion blur, volumetric fog, DOF, HDR. Transparency with deferred rendering is usually solved by splitting the rendering pipeline in two parts [HARRIS07].
1 . Render opaque objects: Render all opaque objects with deferred rendering; perform all three deferred rendering phases to get final composite image.
2. Render transparent objects: Render all transparent objects sorted back to front with traditional rendering to get the final image with all transparent objects and alpha channel, and then blend it over the deferred rendering final composite image.
The biggest problem in this method is lighting inconsistency (since deferred rendering can handle lights more efficiently than traditional forward rendering). Another problem is the additional administration and code required to handle the split pipelines and traditional rendering required for transparent objects.
samples into the final image, which is not usually supported with deferred rendering.
My contribution is a new approach for supporting transparency in deferred rendering: an algorithm that solves the lighting consistency problem of the transparent objects when using the deferred rendering method.
The advantages of this approach are:
Lighting consistency: Opaque and transparent objects use the same lighting pipeline, resulting in the same lighting quality. Opaque objects can gradually fade out without any lighting glitches.
Simple and robust: The method requires no pipeline changes and no additional object sorting (which is usually required for transparency rendering) or any other object separation between opaque and transparent objects. It can handle both vertex- and texture-level transparency with no additional coding.
Speed: The method adds only 7 to 10 pixel shader instructions and two texture fetches and requires no additional render targets switching.
OVERVIEW
Deferred rendering transparency requires two pixel shader code fragments to be inserted into the existing deferred rendering implementation: one in the geometry phase, which interlaces transparent objects, and one in the composition phase, which de-interlaces and blends transparent objects with background.
In the G-buffer creation phase, all transparent pixels are rendered interlaced (Figure 2.7.2); only every odd horizontal line is rendered (implementation can be easily adjusted for vertical lines or zigzags), and pixel alpha values are stored in color alpha channels. This is done with a very simple pixel shader fragment that uses pixel shader 3 VPOS register (it can also be done with a vertex shader-prepared variable on pixel shader 2 hardware) and an alpha test that filters out odd lines where alpha is set to zero.
FIGURE 2.7.2 The color buffer after the G-buffer creation phase. Transparency is shown in smaller rectangles in the lower left corner of each pixel.
In the composition phase, the minimal alpha value is taken from the current pixel and the pixel above (or below). If the minimal alpha is less than 1, then both pixels are blended together and de-interlaced with the transparency formula (Figure 2.7.3).
FIGURE 2.7.3 Compositing and de-interlacing the image. Within each two rows, the minimum alpha value across the two vertically adjacent pixels is taken, and the two pixels are blended.
RENDERING
This section explains the technique in detail. Note that the implementation described here is written for pixel shader 3, but it can be easily adopted for pixel shader 2. Also, while we use horizontal lines to perform the transparency blend, vertical or zigzag patterns can be also implemented.
G
EOMETRYP
HASEIn the G-buffer creation phase, we render all objects: opaque and transparent, and in any order (no need to alpha sort or draw transparent objects separately). However, sorting from front to back is usually better since current hardware can do rejects very fast.
When rendering during this phase, we activate alpha testing with a zero reference value and the test function set to Greater.
A l phaT es tE nabl e = true; A l phaFunc = Greater; A l phaRef = 0;
The pixel shader sets the alpha value of transparent pixels in odd lines to zero, so they get skipped by the alpha test, while pixels in even lines are left unchanged. This trick produces interlaced transparent objects that will be combined into the final image in the composition phase. The code below is responsible for calculating the correct alpha value for interlacing:
fl oat al pha = tCol or.a; i f (al pha < 0.99)
al pha *= frac (i nS P os .y * 0.5) < 0.1;
The output alpha value must be stored in an alpha channel (e.g., along with the RGB color).
After this phase, we execute the lighting pass normally without any changes. Then we move to the next phase.
C
OMPOSITIONP
HASEIn this phase, color and lighting render targets are composed into a final composite image.
The pixel shader deinterlaces and blends transparent objects with the background. Note that all pixels must be processed; otherwise, transparent objects will not get de-interlaced (so image masking techniques like stencil testing must be handled with care).
The pixel shader basically samples at two positions: color and light at the current pixel and one pixel above. The minimal alpha value between both colors is calculated and is used to blend the two pixel values.
Although this basic de-interlacing approach is fast, it introduces some artifacts that are shown in Figure 2.7.4.
FIGURE 2.7.4 Artifacts showing at the edges of the alpha-blended part of the geometry due to the simplistic de-interlacing approach used to compose the final image.
One quick fix for this problem is to sample one more pixel below, take the minimal alpha value between the three pixels we have, and use the result as the blend value.
Here is the new pixel shader code for the composition phase to handle deinterlacing:
fl oat2 uv1 = i nT ex0 − fl oat2(0, T Devi c eS i ze.y); fl oat2 uv2 = i nT ex0 + fl oat2(0, T Devi c eS i ze.y);
fl oat4 c ol orA = tex2D(Col or0P oi ntS am pl er, i nT ex0); // Current pi xel fl oat4 c ol orB = tex2D(Col or0S am pl erP oi nt, uv1); // P i xel above fl oat4 c ol orC = tex2D(Col or0S am pl erP oi nt, uv2); // P i xel bel ow fl oat4 l i ghtA = tex2D(Col or1P oi ntS am pl er, i nT ex0); // Current pi xel fl oat4 l i ghtB = tex2D(Col or1S am pl erP oi nt, uv1); // P i xel above
c ol orB .a = m i n(c ol orB .a, c ol orC.a);
fl oat a = c ol orA .a; i f (c ol orB .a < c ol orA .a) a = 1 - c ol orB .a;
fl oat4 c ol or = l erp(c ol orB , c ol orA , a); fl oat4 l i ght = l erp(l i ghtB , l i ghtA , a);
// now us e c ol or and l i ght i n the us ual l i ghti ng c al c ul ati ons