Linear sRGB Blending & Deferred Lighting (ver. 2)
Tuesday, May 25, 2010 at 8:12PM
n00body in Deferred Shading, Encoding

Since my new computer's is equipped with an SM 4.0 graphics card, I decided to play around with some features that were standardized for this class of GPU. In particular, I was interested in how they now correctly perform linear blending when using sRGB rendertargets. This means that I get the correct color results of linear blending, but the concentrated precision of automatic sRGB conversion.

 

This is relevant to my project because I have read about other Deferred Renderers using this feature on consoles to avoid needing high precision lighting buffers. So it seemed like a good opportunity to dust off my old Deferred Ligthing code, and see how it could benefit from this approach.

 

If you are unfamiliar with sRGB and Gamma-space, the following links will provide a far better explanation than I could.

 

Links:

[1] RenderWonk: Adventures with Gamma-Correct Rendering

[2] blog.illuminate.labs: Are you Gamma Correct?

[3] Gamefest Unplugged (Europe) 2007: HDR The Bungie Way

 

Tests:

For my experiment, I used a scene with six point lights of varying intensities. The data is stored in the range [0,2] in RGBA8 buffers so I can get Medium Dynamic Range lighting. I'm using standard Lambertian diffuse lighting, and Normalized Phong for specular. The defining difference here is whether it uses a standard RGBA8 buffer storing linear values, or an RGBA8_sRGB buffer storing gamma-space values.

 

For the sake of completeness, I have decided to test both of the common Deferred Lighting light accumulation variations. The first having two render targets, to accumulate diffuse and specular lighting independently. The second having one render target that stores diffuse lighting and specular intensity,  approximating colored specular lighting via the diffuse lighting chromacity.

 

Results:

For the two RT approach, the difference between the raw linear RGB and linear sRGB blending versions is pretty dramatic. The diffuse lighting sees significantly less banding in the center of dim light contributions, and has a smooth falloff out to their edges. The specular light contributions only see improvements around their edges, yielding a subtle but noticeable difference. In both cases, the overall lighting quality is significantly better.

 

The one RT approach had the same diffuse lighting quality as the two RTs approach, but only marginally improved specular lighting. I had concerns about using the sRGB trick with this approach because automatic sRGB conversion doesn't affect the alpha channel. Not so surprisingly, the stored specular intensity produces nasty banding artifacts in the colored specular lighting approximation regardless of whether or not linear sRGB blending is being used.

 

2RT, sRGB:

sRGB - Diffuse sRGB - Gloss 1 sRGB - Gloss 47 sRGB - Gloss 256

Figure 1, 1, Diffuse; 2, Gloss - 1; 3, Gloss - 47; 4, Gloss - 256

 

2RT, RGB:

RGB - Diffuse RGB - Gloss 1 RGB - Gloss 47 RGB - Gloss 256

Figure 2, 1, Diffuse; 2, Gloss - 1; 3, Gloss - 47; 4, Gloss - 256

 

 

1RT, sRGB:

1RT sRGB -  Gloss 1 1RT sRGB -  Gloss 47 1RT sRGB -  Gloss 256

Figure 3, 1, Gloss - 1; 2, Gloss - 47; 3, Gloss - 256

 

1RT, RGB:

1RT RGB -  Gloss 1 1RT RGB -  Gloss 47 1RT RGB -  Gloss 256

Figure 4, 1, Gloss - 1; 2, Gloss - 47; 3, Gloss - 256

 

Conclusion:

All in all, I'd say this approach produces some really nice results when compared against using high-precision buffers. This way, I get the storage cost & read/write bandwidth of an RGBA8 buffer, but with the blending & precision benefits that would normally necessitate an RGBA16F buffer. For this reason, I am strongly considering this approach over floating point buffers on SM 4.0 hardware.

 

Just have to wait and see I guess.

Article originally appeared on Crunchy Bytes (http://n00body.squarespace.com/).
See website for complete article licensing information.