POC : Introduction to a new experimental module: "3D Colorimetric Film (3DCF)"

Hello,

While working on the ACES 2.0 module, I discovered a bug in the SSTS curve.

The SSTS normalization used / n (peak luminance) instead of / n_r (reference luminance, 100 nits). This inverted the peak ↔ brightness relationship: increasing the peak made the image darker instead of giving more highlight headroom. The behavior is now aligned with ACES 2.0 (ssts_fwd(x) / n_r).

New sliders (replacing the old “perceptual brightness”)

Slider Role Range
Input exposure Pre-SSTS exposure in EV −2 to +2 EV, default 0
Peak luminance SSTS peak luminance (curve character) −100% to +100%, 0% = 200 nits (ACES 2.0 ref.)

Peak is decoupled from exposure: Peak luminance controls the curve roll-off (higher peak = softer compression), Input exposure controls exposure independently.

Abney rotation — new formulation

The old hl_hue_shift used an arbitrary luminance threshold (st_desat_weight based on y_exposed). The rotation was often imperceptible.

New approach: the rotation angle is tied to the actual SSTS compression ratio:

compression = min(y_tm / (y_abs × EV), 1.0)   // 0 = heavily compressed, 1 = linear
weight      = pow(1.0 - compression, exponent)
exponent    = max(1.0 − |hl_hue_shift|, 0.1)
angle       = hl_hue_shift × 1.0 × weight
  • hl_hue_shift = 0: no rotation
  • hl_hue_shift > 0: rotation increases with compression, smooth transition
  • hl_hue_shift = +1.0: progressive rotation from compressed highlights toward midtones

Out-of-gamut yellows are automatically chroma-clamped (rotation scaled to stay within [0,1]) with no hue artifacts.

I’ll take a look tonight or tomorrow at the bug you’re having with the AGX slider.
Have a nice day,
Christian,
P.S. I won’t be talking about soccer today, :wink: