Linear Lighting in DirectX Render Targets

A linear lighting workflow is foundational to physically based rendering and correct image synthesis in modern graphics pipelines. Maintaining linear color values across all intermediate DirectX render targets ensures that mathematical operations—such as light accumulation, alpha blending, filtering, and post-processing effects—accurately replicate the physical behavior of light. This article covers why intermediate non-linear conversions introduce visual artifacts, how gamma-space calculations distort light physics, and how to properly utilize DirectX formats to preserve linearity from scene shading to final display output.

The Physics of Light vs. Gamma Correction

Physical light behaves linearly: doubling the number of identical photons emitted into an environment doubles the measured radiant intensity. Computer rendering formulas, including the rendering equation, Lambertian reflectance, and specular microfacet models (such as GGX), operate exclusively under this assumption of linear light transport.

Monitors, however, historically used a non-linear power curve (roughly \(V^{2.2}\), standardized as sRGB) to represent intensity, matching the electrical characteristics of CRTs and roughly corresponding to the non-linear way the human eye perceives brightness. While the final output presented to the display must be encoded to sRGB so the display converts it back to linear light for the eye, all intermediate calculations and render passes must occur in a linear color space.

Why Intermediate Render Targets Must Remain Linear

When rendering occurs over multiple passes—such as in deferred rendering, shadow mapping, ambient occlusion, depth-of-field, bloom, and HDR tone mapping—render target textures store intermediate results. Introducing non-linear (gamma-encoded) values into these intermediate targets corrupts rendering in several distinct ways:

1. Correct Hardware Alpha Blending

Alpha blending in DirectX executes fixed-function hardware operations:

\[\text{Color}_{\text{result}} = \text{Color}_{\text{src}} \times \alpha + \text{Color}_{\text{dest}} \times (1 - \alpha)\]

This formula is inherently linear. If an intermediate render target stores gamma-encoded color values, the blending hardware treats those values as linear. Blending two gamma-encoded values produces an unnaturally dark boundary where they overlap. For translucent objects, particles, and anti-aliased geometry, this causes visible dark fringing, muddy edges, and an incorrect loss of perceived energy.

2. Accurate Texture Filtering and Downsampling

Most post-processing chains (such as downsampling for bloom or depth-of-field blur chains) sample intermediate render targets using bilinear or bicubic filtering. Linear interpolation between two pixels assumes that the midpoint value represents the midpoint of physical intensity:

\[\text{Sample} = 0.5 \times A + 0.5 \times B\]

When the values \(A\) and \(B\) are non-linear, the arithmetic mean does not match the radiometric mean. Downsampling gamma-encoded targets leads to significant loss of light energy, making blurred lights look noticeably dimmer and altering the expected shape of blur kernels.

3. Physically Meaningful High Dynamic Range (HDR) and Post-Processing

Modern rendering pipelines rely on values that exceed 1.0 (HDR) to represent intense sunlight, reflections, and emissive materials. Intermediate render targets frequently use floating-point formats to store these values.

Post-processing passes such as tone mapping, bloom isolation, and exposure adjustment assume that a pixel value of 10.0 represents ten times the intensity of 1.0. If intermediate targets apply an sRGB or gamma transformation prematurely, dynamic range is severely compressed, thresholding operations for bloom fail, and tone mapping curves map colors to unexpected display values.

4. Multisample Anti-Aliasing (MSAA) Resolve

When MSAA targets are resolved into intermediate textures, the hardware averages samples within each pixel. Resolving an MSAA target containing non-linear values darkens high-contrast geometric edges (such as bright edges against dark backgrounds), negating the smoothing benefits of anti-aliasing and creating noticeable jagged silhouettes.

DirectX Implementation Best Practices

To maintain a linear pipeline throughout intermediate render targets in DirectX 11 and DirectX 12:

  • Use Explicit sRGB Formats for 8-bit Targets: When using 8-bit per channel textures (such as DXGI_FORMAT_R8G8B8A8_TYPELESS), create Shader Resource Views (SRVs) and Render Target Views (RTVs) using DXGI_FORMAT_R8G8B8A8_UNORM_SRGB. The GPU hardware will automatically convert sRGB texture data to linear space on texture fetches and convert linear values back to sRGB on render target writes.
  • Use Floating-Point Formats for HDR Buffers: Intermediate render targets for deferred G-buffers, lighting accumulation, and post-processing should typically use DXGI_FORMAT_R16G16B16A16_FLOAT or DXGI_FORMAT_R11G11B10_FLOAT. Floating-point formats are inherently linear and do not use sRGB hardware conversions.
  • Defer Display Encoding to the Final Pass: Keep every intermediate pass strictly linear. Only apply the sRGB transfer function or display tone mapping in the very last post-processing pass directly writing to the swap chain back buffer.