The last note owned environment lighting as a multiply: a GGX-prefiltered cube times a DFG LUT, plus distant irradiance. Display was a named footnote there:
TM was Khronos PBR Neutral, exposure 1.05, identical on every IBL comparison row, not baked into the cubemaps. The IBL out-of-scope line was explicit: deep tone-map bake-off (TM is one named operator). This note owns that operator. Tone mapping allocates display codes; it does not create lighting.

The same loft still the IBL note already earned: cream stoneware (dielectric , glaze roughness –) and measured brass on a board-formed concrete catcher, loft window behind, grounded contact. Named operator, exposure 1.05. The metal still carries mullions. The glaze still reads cream. HUD: Khronos PBR Neutral exposure=1.05, photo-only - no metric. Caption on the plate: tone mapping allocates display codes; it does not create lighting. Do not hang a clip-fraction on this photograph.

Controlled failure on the identical float buffer. Left burns any channel to display white. Right compresses the peak and keeps brass hue. Same . Caption on the plate: not IBL-10: that plate clipped before prefilter. this clips after shading. Photo only. The full-frame pair does not make the mullion crush obvious.

Pin this. Tight crop of the brass window specular, nearest upscale. Left CLIP — blown: channel-1 pancake, mullion grid gone. Middle NEUTRAL — structure: bars still there, brass tint still there. Right : heat where clip and Neutral disagree. If the L/R pair looked similar from across the room, this crop is the proof.
Hero, Mesa 25.0.7 llvmpipe, linear working space, Khronos PBR Neutral (, , ), exposure 1.05: env solid-angle mean luma 1.628; linear plate 48.22, 1.302. Before TM at : clip_frac 0.13355, highlight RMS 7.660, midtone mean 0.481. After clip/sat: sat_frac 0.134, highlight RMS 0.686, midtones unchanged 0.481. After Neutral: clip_frac 0, highlight RMS 0.625, midtone 0.441. Assertions 31 pass / 0 fail.
What you are seeing
Working space is scene-referred linear Rec.709 radiance. One RGBA32F loft still, shaded once. Camera, materials, env, and split-sum tables are IBL-continuous (eye (1.30, 0.54, 1.98) → (0.05, 0.25, 0.02), fov ). This note does not re-derive Karis, DFG, or distant . It changes the display operator.
Presentation hook. Product still, , GL photograph, CPU tone map. Named display operator. Photo only.
Controlled failure. L/R, . Identical float buffer, same exposure, only TM differs. The full-frame pair is a quiet product still. The brass-window mullion crush lives in the teaching zooms.

Four-up of the same crop, nearest. (1) hard clip/sat, specular is a flat white pancake. (2) Neutral, mullion bar + brass hue still there. (3) clip with fail pixels marked: red = channel-1 white where Neutral keeps structure. (4) heat. Caption on the plate: if panel 1 vs 2 still looks similar from afar, trust panel 4.

Same L/R as the controlled failure, callouts on the brass specular: left hard clip/sat, hue crushed to channel-1; right Neutral, mullion / brass color kept.
Two facts, never mixed:
- Beauty plates (hero, clip-vs-Neutral, exposure ladder, Reinhard / ACES / luma controls) are GL-rendered split-sum, then a named CPU TM, then sRGB OETF. HUD
photo-onlymeans do not invent a clip-fraction or RMS theorem from the JPEG. - Instruments (false-color , curve-on-hist of , clip-mask of , and the CSV) are the float buffer. The teaching zooms are nearest-upscale crops of the L/R pair so the failure is readable.
Scene-referred, display-referred, then 8-bit
Three spaces. Mixing them is how people “fix lighting” with a tone curve.
- Scene-referred linear. is radiance after shading. Values are legal. This plate: , . At , 276928 pixels have any channel (clip_frac 0.13355).
- Display-referred linear. After TM, (Neutral and per-channel Reinhard land here; luma-ratio Reinhard can still overshoot a channel and needs a final sat). This is what a display code of 1 means in this note.
- 8-bit sRGB PNG. The OETF is IEC 61966-2-1 piecewise, not . PNG 255 is not linear 1. Measurement is the float buffer / CSV. Do not FFT or energy-integrate the JPEG.
IBL-10 is not this failure. That plate authored before prefilter: the environment never had HDR, so the metal lost punch and the interior collapsed. These plates clip after shading, on a float loft that does have HDR (env mean luma 1.628). Same visual family, different theorem. Stated on the L/R pair and the clip-mask.
Why: expose, then a named curve, then OETF
Shade once into RGBA32F. Operator rows change only TM + encode. is a stated gain, not Neutral’s , not an auto-exposure meter.
Exposure is a separate pre-TM gain
Default lock on every operator comparison (IBL continuity). The exposure ladder varies under one fixed curve. Neutral’s is not retuned.
Clip / saturate — controlled failure
No shoulder. Any channel becomes display white. Hue of a clipped brass highlight is whatever channel survived. Shiny white and matte white become the same code. The product still dies. That is the left panel of the L/R pair, and the pancake in the teaching zoom.
Reinhard — labeled control
Global form:
Never reaches 1. Two application modes, one control plate:
- Per-channel. Apply to independently. Highlights desaturate toward grey; brass hue walks. Midtones on this crop: 0.325 (pulled vs Neutral’s 1:1-ish band).
- Luminance-ratio. Rec.709 luma , , . Hue-preserving; a channel can still exceed 1 before the final sat (clip_frac 0.056 on ).
Extended white-point Reinhard is mention-only, not a hero.
Narkowicz ACES — labeled control (album continuity)
Older sampling notes displayed with ACES (Narkowicz) then . Keep that operator as a labeled control, not the hero. No silent pre-scale.
Per-channel. On this midtone crop ACES mean 0.604 sits above Neutral 0.441 and even above 0.481: Narkowicz around has gain . That is filmic contrast, not a Neutral defect, and not a claim that ACES is wrong.
Khronos PBR Neutral — named hero
Linear Rec.709 in, linear Rec.709 in out. Constants from the Khronos spec / pbrNeutral.glsl, not re-fit. Cite KhronosGroup/ToneMapping PBR_Neutral. No gamut mapping in this note.
Three stages:
- Toe. Offset from so darks are not a raw 1:1 that looks desaturated under Fresnel-aware PBR. is the dielectric normal-incidence term Neutral is built around:
-
Mid. 1:1-ish after that offset for base colors in the band (sRGB 80–231 under unitary white). Peak . If , return . That band is why Neutral is the product-still operator. On this ceramic/catcher crop the midtone is mean minus the offset exactly: 0.4815 − 0.04 = 0.4415. Gray slice asserted: Neutral.
-
Shoulder. Peak compression starts at . Let :
Then mix toward at mix . Desaturation toward the compressed peak at rate .
Neutral is the named product-still display operator, not “correct cinematography.”
Display-referred range, then OETF
After TM, is display-referred linear. Then the sRGB OETF (IEC 61966-2-1 piecewise):
PNG write is this encode. GL_FRAMEBUFFER_SRGB is off. Measurement is the float buffer, not the PNG.
Unique artifact: this plate’s histogram, these curves

This is the thing this note exists to draw. Log- scene-referred , same loft buffer as the beauty rows, clip drawn as a wall at 1. Overlay: clip/sat (hits 1 and stays), Neutral (gold, 1:1-ish through the mid, shoulder after ), Narkowicz ACES (magenta, gain in the mids on this plate), Reinhard (cyan, never reaches 1). Thumbnail of this still so it cannot be a stock filmic screenshot.
Honesty on the overlay: Neutral’s peak compression plus desat-toward-white is RGB. The plotted curve is grayscale Neutral(Y,Y,Y), labeled on the plate. Gold band on the legend is , the 1:1-ish claim.

Instrument, not a hero. before exposure and TM, turbo, color bar in linear from 0.01 to 31.6, tick at . Window glass and the brass reflection sit well above 1. Values are legal scene-referred radiance.
False-color is before exposure. The histogram is with so the wall at 1 matches the clip operator. Do not mix those two s.

Neutral photograph plus red overlay where any channel , plus a brass/window crop: clip flattens, Neutral keeps highlight structure. Red is the pixels burns to channel-1. Neutral compresses the peak. Same theorem as the teaching zoom, painted on the whole plate.
Quote the CSV. Do not quote the beauty photographs as meters.
Float buffer, Mesa llvmpipe. Highlight crop: brass window specular –, . Midtone crop: ceramic/catcher away from the window spec –, . unless the row is the Neutral ladder.
| stage | operator | clip_frac | sat_frac | highlight RMS | midtone mean |
|---|---|---|---|---|---|
| before TM | identity | 0.13355 | 0.13362 | 7.660 | 0.4815 |
| after TM | clip/sat | 0 | 0.13362 | 0.686 | 0.4815 |
| after TM | Reinhard per-channel | 0 | 0 | 0.562 | 0.325 |
| after TM | Reinhard luma-ratio | 0.05607 | 0.05657 | 0.564 | 0.325 |
| after TM | Narkowicz ACES | 0 | 0.06453 | 0.717 | 0.604 |
| after TM | PBR Neutral | 0 | 0.00004 | 0.625 | 0.4415 |
Neutral exposure ladder (curve fixed, not retuned):
| highlight RMS | midtone mean | clip_frac after Neutral | |
|---|---|---|---|
| 0.50 | 0.530 | 0.189 | 0 |
| 1.05 | 0.625 | 0.441 | 0 |
| 2.00 | 0.758 | 0.817 | 0 |
Env solid-angle mean luma 1.628. Linear plate 48.22, 1.302. FBO RGBA32F ; 8-bit fallback not hit.
Hero rounding used in the lede: clip_frac 0.13355; highlight RMS 7.660 → 0.686 (clip) / 0.625 (Neutral); midtones 0.481 (clip, unchanged) / 0.441 (Neutral) / 0.325 (Reinhard RGB); ladder 0.189 / 0.441 / 0.817. Do not invent a clip-fraction or RMS theorem from the hero, the L/R pair, or the Reinhard plate. Those frames are photo-only.
Highlight RMS is photometric, not a structure meter. After clip, crop RMS is 0.686 (many pixels parked at 1). After Neutral it is 0.625 (shoulder below 1). Clip RMS Neutral RMS is not Neutral “losing” highlights. Structure (mullions in the brass reflection) is the clip-mask and the teaching zoom, not the RMS ranking.
Failures / controls
Clip vs Neutral
The L/R pair plus the obvious zooms plus the clip-mask. Clip-fraction of is the input fact (0.13355). After clip, that fraction is burned into channel-1 (sat_frac 0.134, midtones untouched at 0.481). After Neutral, clip-fraction of is 0; sat_frac is (a handful of pixels at the compressed peak ), highlight structure remains. This is the controlled failure, not a contestant.
The zooms exist because the full-frame L/R is a quiet product still. The tight crop is the brass-window mullion grid: clip is a white rectangle; Neutral still has bars. The four-up panel 4 is the heat proof if the photographs still look close. The clip-mask paints the same pixels red on the Neutral plate (window, glaze rims, brass spec) and repeats the crop.
Exposure ladder under one curve

Neutral only. underexposes the glaze (midtone 0.189). is the lock (midtone 0.441). drives more of the window into Neutral’s shoulder (midtone 0.817, highlight RMS 0.758). Clip-frac after Neutral stays 0 at all three gains. Not auto-exposure. is not retuned. The scientific point is the split: gain first, curve second.
Reinhard vs Neutral

Same buffer, same . Reinhard per RGB never reaches 1 and pulls cream glaze / concrete midtones down (0.325 vs Neutral 0.441 vs 0.481). Neutral keeps a 1:1-ish base-color band. Reinhard is a labeled control, not a second hero.
ACES vs Neutral

Same buffer, same . ACES is the older album default. Caption on the plate: not a claim that ACES is wrong cinematography. Midtone mean 0.604 is the filmic contrast already quoted. No input pre-scale.
Per-channel vs luminance Reinhard (brass hue)

Control plate, not a second hero. Measured brass is colored. Per-channel Reinhard greys the highlight (the crop walks toward white-grey). Luma-ratio keeps hue; a channel can still exceed 1 before final display sat (clip_frac 0.056). Per-channel TM is a hue operator in disguise. Neutral’s peak-based compression plus desat-toward-white is a different, stated choice.
Two paths, do not mix the instruments
| path | frames | instrument |
|---|---|---|
| Photograph | hero, L/R pair, exposure ladder, Reinhard / ACES / luma controls | GLSL 330 split-sum on this llvmpipe into RGBA32F, then CPU TM + sRGB OETF. HUD photo-only. |
| Instrument | false-color, curve-on-hist, clip-mask, CSV | false-color , curve-on-hist of , clip-mask of , linear-crop meters. |
| Teaching zoom | callouts, tight crop, four-up | nearest-upscale of the brass-window specular so the mullion crush is readable. |
| Display | every plate | expose → named TM → sRGB OETF. One linear . Operator is the knob. |
The L/R pair is a photograph of the control and the source of the teaching zooms. Quote the CSV for clip-frac and RMS. Do not quote the 8-bit panel as 0.13355.
Honesty gaps
- Neutral is the named product-still display operator, not “correct cinematography.” ACES is a labeled control (older album default). Reinhard is a labeled control. Clip is the controlled failure.
- Highlight RMS is photometric, not a structure meter. Clip RMS 0.686 vs Neutral 0.625 does not rank highlight quality. Structure is the clip-mask and the teaching zoom.
- ACES midtone mean (0.604) sits above Neutral (0.441) and even above (0.481) on this crop. Narkowicz around has gain . Filmic contrast, not a Neutral defect.
- Neutral sat_frac is , not identically 0. A handful of pixels sit at the compressed peak .
clip_frac(any channel ) is 0. - Reinhard luma-ratio still needs a final display sat for PNG (clip_frac 0.056 on before sat). Per-channel Reinhard never reaches 1.
- Curve overlay on the histogram is grayscale
TM(Y,Y,Y). Neutral’s peak compression + desat-toward-white is RGB; the overlay is labeledNeutral(Y,Y,Y). - False-color is before exposure. Histogram is with so the wall at 1 matches the clip operator.
- This clip is post-shading , not IBL-10. IBL-10 clipped before prefilter (source never had HDR). Same visual family, different theorem.
- TM does not create lighting. Same , same env, same materials. The curve only allocates display codes.
- Contact AO is a planar cosine term, not a shadow map. Env is procedural loft HDR, not a captured EXR.
- No hardware tonemap unit, no PQ/HDR10, no OCIO cinema LUT, no local adaptive TM as hero. Neutral’s current spec is sRGB. Local TM exists; it is not this plate.
- JPEG / PNG is 8-bit display-referred. Do not FFT or energy-integrate the file. Midtone mean and highlight RMS are linear-crop meters.
- IBL tables are reused, not proven here. Seamless-cube face edges,
glGenerateMipmap, prefilter spp caveats stay in the IBL note.
Mesa / llvmpipe — what this run can claim
| item | value |
|---|---|
GL_VERSION |
4.5 (Core Profile) Mesa 25.0.7-2+deb13u1 |
GL_RENDERER |
llvmpipe (LLVM 19.1.7, 256 bits) |
| FBO color | RGBA32F complete, . 8-bit fallback not hit |
| Specular / irradiance / sky cubes | RGBA16F cubemaps, CPU mips uploaded per level. glGenerateMipmap not called |
| DFG LUT | RGBA32F , CPU GGX (reused IBL integrator, not re-derived as a theorem) |
GL_FRAMEBUFFER_SRGB |
disabled (TM + sRGB OETF on CPU) |
| MSAA | disabled |
| Neutral gamut | Rec.709 in, Rec.709 out, no gamut mapping |
| Exposure / TM | 1.05 / Khronos PBR Neutral (, , ) |
Can claim: on this llvmpipe build, one linear HDR loft buffer, exposed by a stated gain, produces these photographs under clip / Reinhard / ACES / Neutral; clip-fraction, highlight RMS, and midtone mean move as the CSV says; Neutral is the named display operator carried forward from IBL.
Cannot claim: that Neutral is “correct cinematography,” that ACES is wrong, that a JPEG histogram is the scene histogram, that PNG 255 is linear 1, that changing the curve invented lighting, or that this is how a display chip’s tonemap unit works. Discrete-GPU metrics, occupancy, bandwidth, HDR10/PQ encode, OCIO cinema LUTs.
Assertions
This run: 31 pass / 0 fail.
| check | result |
|---|---|
| Required gallery plates + CSV exist and are non-empty | PASS |
| FBO is RGBA32F; 8-bit fallback not hit | PASS |
| No NaNs in | PASS |
| Env mean luma in | PASS 1.628 |
Cube upload not fail |
PASS RGBA16F |
| clip-frac | PASS 0.13355 |
| Neutral clip-frac | PASS 0 |
| Clip sat-frac tracks input clip-frac | PASS 0.13362 |
| Highlight RMS drops under clip and Neutral vs | PASS 7.660 → 0.686 / 0.625 |
| Reinhard per-channel midtones below Neutral in the 1:1 band | PASS 0.325 < 0.441 |
| Neutral gray slice (F90 offset, not re-fit) | PASS |
| Neutral constants not re-fit | PASS |
No assert tolerances were loosened for the photoreal plates.
Out of scope
Full cinema LUT pipelines, OCIO shows, film print emulations, AgX / Hable / Uncharted2 as additional heroes. HDR10 / PQ / HLG / Rec.2020 mastering (Neutral’s current spec is sRGB). Local adaptive / operator-TMO / bilateral / photographic-zone TM as the hero. Auto-exposure meters, key-value, histogram-centering as the primary subject ( is a stated gain). Color-management ICC / display-profile rabbit hole. sRGB-vs-linear texture decode. TAA, temporal accumulation, firefly-suppression as TM. Re-deriving IBL: Karis prefilter, DFG LUT, roughness→mip, distant . Cite the live note. Toksvig, anisotropic GGX, sheen, clearcoat, layered metals. Shadow-map bias. Hardware “tonemap unit,” real-time cost, occupancy, bandwidth.
Album sequence:
- Perspective-correct — what you interpolate
- Z-fighting — how depth is encoded
- Mipmaps — which frequencies survive an isotropic minify
- Anisotropic — which UV ellipse that pixel covers
- Parallax occlusion — fake depth from a height field; the silhouette is still the quad
- Split-sum IBL — environment lighting as a multiply: GGX-prefiltered cube DFG, plus distant
- Tone mapping — scene-referred to display-referred; the curve allocates codes, it does not create lighting
Display lock
Le = e * Lo
Ld = TM(Le) // Neutral hero; clip / Reinhard / ACES are labeled
sRGB = OETF(sat(Ld))
Locked Neutral constants (not re-fit): , , . Rec.709 in/out. Pin the hero as the presentation. Pin the tight crop as the failure. Pin the histogram as the unique artifact. The formula is the caption. Same . The curve only allocates display codes.