The scene on the right is rendered once to an off-screen buffer, then re-drawn to the screen through a second GPU pass — a color-grading shader — exactly like the RAW-processing pipeline inside Lightroom or Photoshop's Camera Raw filter. Each control is one term applied per pixel, in linear order:
c *= 2^EV // exposure: one stop doubles light
c.r *= wb_r; c.b *= wb_b // white balance: scale channels to cancel a color cast
c = (c - 0.5) * (1 + K) + 0.5 // contrast: pivot around mid-gray
L = 0.2126r + 0.7152g + 0.0722b // Rec.709 luma
c = mix(vec3(L), c, 1 + S) // saturation: blend toward/away from grayscale
- Exposure multiplies every channel by 2EV, matching how a camera's f-stop scale works — +1 EV doubles the light captured.
- White balance scales the red and blue channels oppositely, correcting (or exaggerating) the orange cast of tungsten/sunset light or the blue cast of overcast shade.
- Contrast stretches values away from mid-gray (0.5); above it, shadows get darker and highlights brighter.
- Saturation interpolates each pixel between its own luma-gray value and its original color.
- The histogram is rebuilt every few frames from a 64×64 downsample of the graded image — the same "brightness map" a real editor's histogram panel shows, with clipped-highlight and clipped-shadow percentages read straight off its tails.