Picture Formation June 30, 2026

AgX Picture Formation: how a render becomes a photograph

A guided, interactive tour of the AgX image-formation chain — the inset/outset chromaticity geometry, the per-channel tonescale sigmoid, and the path-to-white it produces. Ported faithfully from the Camera-AgX DaVinci Resolve DCTL.

AgX is a picture-formation chain: it takes open-domain, scene-referred light — the kind a camera or a 3D renderer produces, where highlights run far past 1.0 — and forms it into a displayable image without the harsh hue shifts and clipping that a naive tone curve creates. This post walks through the actual mechanism, ported line-for-line from the Camera-AgX DaVinci Resolve DCTL, with every diagram driven by that same math running in your browser.

If you haven’t met RGB gamuts and primaries yet, the sibling post on gamut mapping lays the groundwork — here we assume you’re comfortable with primaries as a triangle in a chromaticity diagram.

1. The chain

AgX forms a picture in a fixed sequence of steps:

decode input → inset (compress chroma) → working-log → per-channel tonescale → restore gamma → outset (restore chroma) → convert to the output gamut → output transfer

Two ideas do the heavy lifting, and they’re the ones worth understanding: the inset/outset pair that brackets the curve, and the tonescale sigmoid itself. Everything else is plumbing — decoding the camera’s transfer function on the way in, encoding the display’s on the way out.

2. Inset and outset: bending the gamut around the curve

Here’s the move that makes AgX behave. Before the tonescale runs, AgX insets the working primaries — it pulls the red, green and blue corners of the gamut inward, toward the white point. After the curve, it outsets — pushing them back out. Both triangles are derived from the input primaries: the inset from the Attenuation amount, the outset from the Purity amount, with an optional shared Hue Flight rotation.

Drag the sliders below. The left diagram shows the inset (red, with arrows marking how far each primary is dragged toward white); the right shows the outset (green), with the true output gamut dashed for reference.

The key thing to notice: with Purity equal to Attenuation (the default), the outset is the exact inverse of the inset — the green triangle lands right back on the input gamut. So if these two linear matrices just cancel, where does AgX’s famous chroma attenuation come from?

It comes from the non-linear tonescale that runs between them. The inset is a plain linear gamut compression; on its own it’s fully reversible. But once you apply a per-channel sigmoid to the compressed values, the outset can no longer perfectly undo it — and that residual is the gentle desaturation AgX is known for. Inset and outset don’t create the look; they position the gamut so the curve can do its work without tearing.

3. The tonescale

The curve itself is Jed Smith’s two-sided sigmoid. It operates in a normalized log working space — so contrast is even across stops — and pins middle grey at a fixed pivot, rolling the shoulder toward display white and the toe toward black. Crucially, toe and shoulder contrast are tuned independently.

Because the curve is applied per channel (not to luminance), a saturated colour whose channels are far apart gets compressed unevenly: the bright channel hits the shoulder and slows down while the others keep climbing, so the colour drifts toward neutral as it brightens. That’s the mechanism — not a special “desaturate” step, just three independent sigmoids acting on inset-compressed channels.

4. Path to white

Put it together and you get AgX’s signature path to white. Below, a field of saturated hues climbs in exposure (brightest on top). The left grid is the naive result — clamp each channel into range — which clips to flat, posterized primaries. The right grid is the full AgX pipeline: the same colours roll smoothly toward white as they brighten, holding their hue far longer.

This is why AgX reads as photographic. Real film and real sensors desaturate in the highlights; a naive digital curve doesn’t, which is exactly what makes un-formed renders look “CG”. AgX rebuilds that behaviour from first principles — a compressed gamut, a per-channel log sigmoid, and a restore on the way out.

5. Where this runs

Everything above is the real Camera-AgX math, ported to TypeScript and checked against the DCTL (via a Python reference) to within floating-point tolerance — the inset/outset geometry, the RGB→RGB matrices, the camera transfer functions, and the tonescale are identical to what runs on a clip in Resolve. The diagrams aren’t illustrations of the algorithm; they are the algorithm.