This repository collects information about next generation (WIP?) color management in Windows, called “Modern Color” or “Advanced Color”.
This is a long-awaited feature so I dig it out before its offical announcement. No NDA violated here.
Read official announcement and documentation from Microsoft:
or the original reverse-engineered pipeline here.
As of Windows 11 24H2, when an MHC calibration is in effect:
As per documentation, an ICC profile with private extension (MHC ICC profile) is required to use modern capabilities documented above.
MHC2Gen is an experimental tool to generate MHC ICC profiles from existing ICC profile created with some random calibration solution.
Currently, only profiles created with DisplayCAL are tested.
💡 The Windows calibration loader must be enabled to load
MHC2
transform.The last release of DisplayCAL calibration loader unconditionally disables a scheduled task of Windows calibration loader. You may need to re-enable
\Microsoft\Windows\WindowsColorSystem\Calibration Loader
for the profile to be loaded automatically after logout or reboot.
Matrix: [sRGB to XYZ] -> XYZ to sRGB -> sRGB (or some other custom gamut) to Device RGB -> sRGB to XYZ -> [XYZ to sRGB]
LUT: vcgt(sRGB transfer to device transfer)
MHC2Gen sdr-csc [--source-gamut=<sRGB|AdobeRGB|P3D65|BT2020> | --source-gamut-icc=<icc file>] "C:\...\DisplayCAL\storage\...\MODEL #1 2022-01-01 00-00 0.3127x 0.329y sRGB F-S XYZLUT+MTX.icm" "MODEL CSC sRGB.icm"
Matrix: identity
LUT: vcgt, or vcgt(sRGB transfer to device transfer) if --calibrate-transfer
is specified
MHC2Gen sdr-acm [--calibrate-transfer] "C:\...\DisplayCAL\storage\...\MODEL #1 2022-01-01 00-00 0.3127x 0.329y sRGB F-S XYZLUT+MTX.icm" "MODEL SDR ACM.icm"
Matrix: [BT2020 RGB to XYZ] -> XYZ to BT2020 RGB -> BT2020 RGB to Device RGB -> BT2020 RGB to XYZ -> [XYZ to BT2020 RGB]
LUT: vcgt(device transfer evaluated with absolute luminance)
MHC2Gen hdr-decode [--min-nits=<override minimun luminance>] [--man-nits=<override maximum luminance>] "C:\...\DisplayCAL\storage\...\MODEL #1 2022-01-01 00-00 0.3127x 0.329y sRGB F-S XYZLUT+MTX.icm" "MODEL PQ10 decode.icm"
The wire signal is converted to SDR but still tagged HDR. This is tricky to use, you need to put Windows in HDR mode but display in SDR mode, possibly with EDID override and/or OSD settings.
Create the device profile with desired maximum luminance and dynamic (local or global) dimming disabled.
From ledoge/novideo_srgb, another LUT-matrix-LUT solution:
To achieve optimal results, consider creating a custom testchart in DisplayCAL with a high number of neutral (grayscale) patches, such as 256. With that, a grayscale calibration (setting "Tone curve" to anything other than "As measured") should be unnecessary unless your display lacks RGB gain controls, but can lead to better accuracy, especially on poorly behaved displays. The number of colored patches should not matter much. Additionally, configuring DisplayCAL to generate a "Curves + matrix" profile with "Black point compensation" disabled should also result in a lower average error than using an XYZ LUT profile. This advice is based on what worked well for a handful of users, so if you have anything else to add, please let me know.
As of Windows 11 24H2 (26100.1882), only lumi
, MHC2
and primaries values in a “valid” MHC ICC profile are used (tone curves and vcgt
are ignored). Extra calibration to sRGB (or gamma 2.2[^1]) tone response via MHC2
regamma LUT is needed for optimal results. However, with an “invalid” profile, vcgt
will be applied.
Given tone curves in ICC ignored, SDR ACM assumes the display is calibrated to sRGB tone curve, which can be achieved with MHC2 LUT.
It is expected future releases will use more characteristics like tone curves and probably PCS LUT in ICC profile, and preferably without the requirement of MHC2
tag.
Before Windows 11 24H2, SDR Auto Color Management requires a non-HDR-capable display at the moment. You are out of luck of using color managed desktop if your display claims a random HDR mapping (HDRn’t) support.
As of Windows 11 24H2 (26100.1882), the synthetic ICC profile uses gamma 2.2 TRC while actual processing uses sRGB TRC.
Applications with ICC shim will still have MHC2 transform applied.
[^1]: Windows SDK headers suppose a gamma 2.2 transfer (OUTPUT_WIRE_COLOR_SPACE_G22_P709
) but experiments show that assuming an sRGB transfer function gives better average delta-E on verification (this may vary on GPU vendor).