mh_PLAYer - LatLong / CGI Environment LUT Kit
============================================
Kit v1.0  |  requires mh_PLAYer v2.12.2 or newer  |  2026-08-22
(c) 2026 Martin P. Heigan / mh_vfx_tools - anti-matter-3d.com
Licence: CC BY-NC-ND 4.0  (see "Licence & credits" at the end)

Purpose
-------
Three working environment LUTs for latlong / HDRI and CG plate review, and a
reference for how mh_PLAYer's two LUT slots differ. Every value in this document
was measured through the player's own LUT engine, not estimated.

The two slots do different jobs:

  Display Transform > LUT ....... DISPLAY LUT. Replaces the display transform.
                                  Scene-linear in, display-LINEAR out - the
                                  player applies the sRGB encode afterwards, so
                                  a display LUT must NOT bake in sRGB gamma.
  Display Transform > Source LUT  SOURCE / LOOK LUT. Scene-linear in, scene-
                                  linear out, applied BEFORE the display
                                  transform, so you keep sRGB / ACES / OCIO
                                  selectable underneath it.

Files
-----
  mhPLAYer_latlong_LUT_kit_CGI_Unreal_ACES_Viewport_65.cube
        DISPLAY LUT. 65-cube + 4096-point 1D shaper. ACES 1.0 RRT+ODT analytic
        fit with Bradford-derived sRGB <-> AP1 matrices. Load into the LUT slot.

  mhPLAYer_latlong_LUT_kit_LATLONG_HDRI_Ambience_Neutralizer_17.cube
        SOURCE LUT. Bradford chromatic adaptation, 4500K ambience -> D65,
        luminance preserving. Neutralises a warm cast in a latlong HDRI.

  mhPLAYer_latlong_LUT_kit_PLATE_Linear_to_SlateMatch_17.cube
        SOURCE LUT. Flare subtract 0.004, then per-channel gain
        1.1250 / 1.0778 / 0.9375, so a plate grey card lands on neutral 0.18.

Test 1 - HDRI Ambience Neutraliser
----------------------------------
1. Open a scene-linear latlong EXR (or any linear EXR).
2. Display Transform > Source LUT > Browse... > ..._HDRI_Ambience_Neutralizer_17.cube
   The status line should read:  3D 17^3  +  domain [0.00-16.00]
3. A neutral surface sitting under the 4500K cast reads
       0.2475  0.1800  0.1243     (warm)
   and comes out as
       0.1903  0.1903  0.1903     (neutral - and the same luminance)
   Sample it with the pixel inspector. Luminance is preserved exactly: Rec.709
   luma in and out are both 0.1903, so the correction re-balances without
   changing exposure.

Test 2 - Plate Linear to Slate Match
------------------------------------
1. Load the same LUT slot with ..._PLATE_Linear_to_SlateMatch_17.cube.
2. A plate grey card reading 0.164 / 0.171 / 0.196 comes out at exactly
       0.180  0.180  0.180
3. Deep black goes slightly negative by design - the flare subtraction happens
   before the gain, and the player clips at zero after the source LUT.

Test 3 - CGI / Unreal ACES Viewport
-----------------------------------
1. Open a scene-linear EXR with real highlights (the ACES Sanity Kit chart is
   ideal).
2. Display Transform > LUT > Browse LUT... > ..._CGI_Unreal_ACES_Viewport_65.cube
   The status line should read:  3D 65^3  +  1D shaper 4096  +  domain [0.00-16.00]
3. Compare against Display Transform > ACES Filmic. Both roll highlights off;
   this LUT is the closer fit to the ACES 1.0 output transform that Unreal's
   ACES viewport approximates, while ACES Filmic is the faster Narkowicz curve.
   For a facility-accurate result use the OCIO ACES 2.0 path in the ACES
   Sanity Kit - this LUT is a viewport preview, not a deliverable transform.

Accuracy - measured, not claimed
--------------------------------
The two source LUTs are a 3x3 matrix and a per-channel affine. Both are
multilinear, and trilinear interpolation reproduces multilinear functions
exactly, so a 17-cube is not an approximation. Measured against the exact maths
over 20,000 random scene-linear samples through mh_PLAYer's LUT engine:

  HDRI Ambience Neutraliser ... max error 1.1e-05
  Plate to Slate Match ........ max error 4.8e-06

Both are float32 rounding. A 33- or 65-cube would be six times the file size
and not one bit more accurate.

The viewport LUT is a genuine tone curve and cannot be exact. Its 1D shaper
distributes the 65 cube nodes logarithmically instead of evenly in linear light,
which is what makes it usable at all - the same LUT on a plain linear domain
misses by 6 to 20 code values in the shadows. Measured error in 8-bit sRGB
output against the exact maths:

  neutral ramp, -13 to +4 stops .... max 0.18 code values
  18% grey ......................... 0.15
  1.0 and 4.0 linear ............... 0.07 / 0.02
  mean over 8,800 samples .......... 0.04
  worst case, any colour ........... 9.9  (near-monochromatic laser primaries,
                                     inherent to any 3D LUT of the ACES gamut
                                     compression - Resolve does no better)

Note - shaper support
---------------------
A .cube file may legally carry a 1D shaper and a 3D table together; the shaper
runs first. mh_PLAYer reads that combined form from v2.12.2 onward. Earlier
builds merged the two tables and produced silently wrong pixels, so the viewport
LUT requires v2.12.2 or newer. The two source LUTs are plain 3D tables and load
in any version.

Licence & credits
-----------------
Kit (c) 2026 Martin P. Heigan / mh_vfx_tools, anti-matter-3d.com.
Released under Creative Commons BY-NC-ND 4.0
(https://creativecommons.org/licenses/by-nc-nd/4.0/).

All three LUTs are original works generated for this kit. The ACES tone curve is
the widely published analytic fit of the ACES 1.0 RRT and sRGB ODT; ACES is a
trademark of the Academy of Motion Picture Arts and Sciences and this kit is
independent and not endorsed by the Academy or the ASWF.
