Module: color-utils/aoklab

Provides an `AdaptiveOklab` class for color space conversions. This model modifies the standard Oklab color space to account for perceptual adaptation to different viewing surround conditions (white, gray, dark). **Novel Approach of Adaptive Oklab (AOkLab):** 1. **Foundation in Oklab:** AOkLab builds upon the standard Oklab transformation pipeline, which typically involves: Linear sRGB -> LMS_Oklab (via Oklab M1 matrix) -> LMS'_Oklab (via cube-root non-linearity, exponent 1/3) -> Oklab L,a,b (via Oklab M2 matrix). 2. **Adaptive Non-linearity:** Instead of the fixed 1/3 exponent, AOkLab introduces a **surround-dependent adaptive exponent `p`**. This `p` is applied to the LMS_Oklab values: `LMS'_adaptive = LMS_Oklab ^ p`. 3. **Goal-Derived Exponents `p`:** The exponents `p` for 'white', 'gray', and 'dark' surrounds are specifically derived to achieve a consistent target *adapted lightness* (L_AOk = 40). This means colors that would have certain *standard Oklab lightnesses* (L_std = 55.9 for white, 48.3 for gray, 41.7 for dark) are all mapped to L_AOk = 40 when processed with the corresponding surround's adaptive exponent `p`. The derivation formula is: `p = ln(0.40) / (3 * ln(L_std_for_surround / 100))`. 4. **Hue Uniformity Correction:** Since the Oklab M2 matrix (LMS' -> Lab) was optimized for the 1/3 exponent, changing this exponent to `p` would alter hue appearance. To preserve hue uniformity relative to standard Oklab, a correction factor is applied to the resulting `a` and `b` opponent channels: `correction = x0 ^ ((1/3) - p)`, where `x0` is a representative LMS value (default 0.5). The final AOkLab `a` and `b` are `a_raw * correction` and `b_raw * correction`. The AOkLab `L` component is taken directly from the M2 matrix transformation. 5. **Pipeline Summary:** - Input (sRGB or XYZ) -> Linear sRGB - Linear sRGB -> LMS_Oklab (using standard Oklab M1 matrix) - LMS_Oklab -> LMS'_adaptive (using exponent `p`) - LMS'_adaptive -> Preliminary L', a', b' (using standard Oklab M2 matrix) - L = L', a = a' * correction, b = b' * correction -> Final AOkLab {L, a, b} The reverse transformations undo these adaptive steps before applying standard Oklab inverse matrices.
Source:
See:

Classes

AdaptiveOklab
AdaptiveOklab