• Why Tone Mapping?

    • Path tracing computes HDR radiance values (can be 0 to thousands of nits)
    • Displays can only show LDR values in [0, 1] (or [0, 1000 nits for HDR displays)
    • Tone mapping compresses the HDR range to the display range
    • Also applies a “filmic” look — mimics how film responds to light

  • Exposure

    • First step: scale radiance by exposure
    • exposed = radiance * exposure
    • exposure = 2^EV where EV is exposure value (stops)
    • Auto-exposure: compute average luminance of the scene, adjust exposure
      • avg_lum = exp(average(log(luminance(pixel) + 0.001)))
      • exposure = key_value / avg_lum where key_value ≈ 0.18 (18% gray)

  • Reinhard Tone Mapping

    • Simple, classic operator
    • L_out = L_in / (1 + L_in)
    • Extended Reinhard (preserves white point):
      • L_out = L_in * (1 + L_in / L_white²) / (1 + L_in)
      • L_white — luminance that maps to pure white
    • Pros: simple, never clips
    • Cons: desaturates highlights, not filmic

  • ACES Filmic Tone Mapping

    • Academy Color Encoding System — industry standard for film
    • Approximation by Krzysztof Narkowicz (widely used in games):
    • Better approximation by Stephen Hill (more accurate to full ACES):
      • Applies an input transform (RRT) and output transform (ODT)
      • Requires color space conversion to ACEScg first
    • Pros: filmic look, good highlight rolloff, industry standard
    • Cons: slightly desaturates, not physically accurate

  • AgX Tone Mapping

    • Troy Sobotka 2022 — used in Blender since 3.x
    • Designed to handle highly saturated colors without hue shifts
    • Better than ACES for path-traced content (less “orange and teal” look)

  • Gamma Correction

    • After tone mapping: apply gamma correction for display
    • sRGB gamma: approximately pow(x, 1/2.2) but with a linear segment near 0
    • Exact sRGB transfer function:
    • Always work in linear space, convert to sRGB only at final output
    • Common mistake: applying gamma twice (once in tone mapper, once in display)

  • Color Space Pipeline

    • Correct pipeline for path tracing:
        1. Compute radiance in linear scene-referred space (ACEScg or sRGB linear)
        1. Apply exposure
        1. Apply tone mapping operator
        1. Apply gamma correction (linear → sRGB)
        1. Output to display
    • Textures: load as sRGB (gamma-encoded), convert to linear before use
      • In Vulkan: use VK_FORMAT_R8G8B8A8_SRGB — GPU auto-converts on sample

  • Luminance

    • Perceptual luminance from RGB: lum = dot(rgb, vec3(0.2126, 0.7152, 0.0722))
    • These weights are the Rec. 709 luminance coefficients
    • Used for: auto-exposure, tone mapping, denoiser guidance