关于 Windows 10/11 的全系统色彩管理 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dant
V2EX    分享发现

关于 Windows 10/11 的全系统色彩管理

  •  4
     
  •   dant 2022-04-14 01:59:51 +08:00 4940 次点击
    这是一个创建于 1352 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Windows 的色彩管理一直是一个非常令人诟病的问题,甚至已经把人逼到去 hook dwm。在当前版本的 Windows 10/11 中,微软静悄悄地加入了两个色彩管理有关的功能:

    一.硬件矩阵变换

    硬件实现的色彩空间转换其实已经不是新鲜事,当前的 GPU 硬件基本都支持在 RGB 通道间进行线性变换,更有甚者提供了 3DLUT ,驱动也提供了对应的用户态 API ,或进一步包装成色彩空间转换 API 。( API 参考:NVIDIAAMDIntel

    而在 Linux drm 框架下,硬件矩阵变换功能对应统一的 drm_color_ctm API ,可以从用户态直接访问,或通过 XRandR CTM API 访问。

    后来 WDDM 规范中加入了矩阵变换作为可选功能,但是并没有说明如何从用户态调用这个功能。

    在 Windows 11 SDK 中,微软提供了一个没有文档、甚至没有对应导出函数的 API:

    // C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\um\Icm.h:1481 #if NTDDI_VERSION >= NTDDI_WIN10_CO struct WCS_DEVICE_VCGT_CAPABILITIES { UINT Size; // Size of structure in bytes BOOL SupportsVcgt; // Indicates if display supports VCGT }; struct WCS_DEVICE_MHC2_CAPABILITIES { UINT Size; // Size of structure in bytes BOOL SupportsMhc2; // Indicates if display supports MHC2 UINT RegammaLutEntryCount; // Max number of entries in the regamma lut // Color space transform (CSC) matrix (row-major) UINT CscXyzMatrixRows; // Number of rows in the color transform matrix UINT CscXyzMatrixColumns; // Number of columns in the color transform matrix }; typedef enum { VideoCardGammaTable = 1, MicrosoftHardwareColorV2 = 2, } WCS_DEVICE_CAPABILITIES_TYPE; /* * Gets the selected display color correction capabilities * * Parameters: * scope specifies the association as system-wide or user-specific * targetAdapterID the target adapter of the display * sourceID the source identifier of the display * capsType the type of capabilities to retrieve (VCGT, MHC2) * outputCapabilities the color correction capabilities to return */ HRESULT WINAPI ColorProfileGetDeviceCapabilities( _In_ WCS_PROFILE_MANAGEMENT_SCOPE scope, _In_ LUID targetAdapterID, _In_ UINT32 sourceID, _In_ WCS_DEVICE_CAPABILITIES_TYPE capsType, _Out_ PVOID outputCapabilities ); #endif //NTDDI_VERSION >= NTDDI_WIN10_CO 

    与此同时,新上市的广色域(指超出 sRGB )笔记本 /显示器附带的 ICC 文件中还包含了一个叫做 MHC2 的神秘 tag ,合理怀疑是与上面的 MicrosoftHardwareColorV2 有关。通过横向对比多个 ICC 文件中的 MHC2 tag 以及一些简单的逆向分析,再结合 SDK 中提供的信息,得出这个 tag 中存放的是屏幕的最高 /最低亮度,以及用于色彩空间转换的矩阵( 4x3 ,猜测是多了一列 offset )和 regamma LUT 。

    鉴于 Windows 应用默认 sRGB 色彩空间,我们可以求得一个矩阵将 sRGB 的三通道亮度转换到设备色彩空间的三通道亮度,然后通过 gamma 曲线和色调响应曲线求出亮度对应的输入信号,从而将屏幕校准为 sRGB 。

    通过校色 ICC 和校准目标 ICC 生成 MHC2 ICC 的工具已发布在 GitHub 上: https://github.com/dantmnf/MHC2

    小插曲

    一开始我的直觉告诉我这个矩阵的输入是 RGB ,于是填了一个 [[0,1,0,0],[1,0,0,0],[0,0,1,0]] 试图交换红色分量和绿色分量,结果发现白点向紫色方向偏移了。后来看到 SDK 里那个 CscXyzMatrixRows,又尝试在 XYZ 空间的白点中交换了 XY ,转换回 RGB 空间后,发现绿色分量变少了。

    后来我在两边各乘了一个 XYZ/RGB 转换矩阵,成功互换了红色分量与绿色分量。但是我依然不能理解为什么一个声称 color space transform/conversion 的矩阵要应用在 XYZ 空间,尤其是变换结果依然当作 XYZ 解释。对此我直呼大脑升级

    此处应有发光大脑 meme 图.jpg

    二、带色彩管理的桌面混成

    在上面的方法中,Windows 依然认为设备色彩空间是 sRGB ,并且通过 GPU 的 display engine 将 framebuffer 中的 sRGB 信号转换为真正的设备色彩空间信号。这种做法不会占用额外的通用计算资源,但同时系统也无法输出在 sRGB 空间外,却在设备色彩空间内的颜色。

    Windows 在引入 HDR 桌面的同时也带来了桌面混成的色彩管理(内部名称 advanced color):支持 advanced color 的应用输出 scRGB 信号,不支持 advanced color 的应用输出被认为是 sRGB 信号,各个应用的输出经混成器( dwm.exe )在 scRGB 空间进行混成后,最终转换为设备色彩空间信号传送到显示器。

    这一过程对 HDR 桌面而言是必须的,但通过逆向分析 dxgkrnl.sys ,发现在特定条件下也可以在 SDR 桌面中强行启用,详见 https://github.com/dantmnf/MHC2#advanced-color-for-sdr 。通过对比多个版本的 dxgkrnl.sys,推断这一功能可能会在 Windows 11 的下一个大版本更新中正式发布。

    (Credit: @imbushuo)

    如果显示器声称支持 HDR ,advanced color 将使用 Rec. 2020 (存疑) + PQ 作为设备色彩空间,由显示器内部转换为合适的面板信号。但对于消费级电子垃圾显示器而言,这个转换过程很可能是不准确且无法校准的。

    不幸的是,在假 HDR* 显示器大行其道的今天,我们很难找到一台广色域但不支持 HDR 的显示器。如果你的显示器声明了假 HDR ,你可以尝试以下方法让 Windows 认为它不支持 HDR:

    • 覆盖 EDID ,删除其中的 HDR static metadata
      • 通过注册表设置 EDID_OVERRIDE(具体效果与驱动有关,可能无法覆盖 HDR 信息)
      • 通过专业显卡的控制面板设置(极高的溢价)
      • 通过可以更改 EDID 的转换盒子(如 3DLUT loader )
      • 自己打板子,拦截 EDID 传输

    很可惜我是属于那种不能覆盖 HDR 信息并且没有专业显卡的,但是已经有两个有钱的群友在多个版本的 Windows 10/11 上测试成功了。

    * 假 HDR ,又称 HDRn’t 、ScamHDR 400

    5 条回复    2022-05-01 15:26:26 +08:00
    4c5577c0ff3f496b
        1
    4c5577c0ff3f496b  
       2022-04-14 02:04:35 +08:00
    这样好.jpg
    qazplkm
        2
    qazplkm  
       2022-04-14 03:04:43 +08:00
    苹果那玩意不适合 Windows 。用 LG OLED 电视或者 EP950 显示器
    carlist
        3
    carlist  
       2022-04-14 08:24:27 +08:00
    从显示器厂商的角度说说
    最恶心人的就是 HDR 标定 - 锁死所有调整参数只能那么用
    所以这个 HDR 就是垃圾

    色彩偏移是硬件转换标定的锅
    叫电脑老老实实的输出 SRGB 信号就行了
    没必要故意偏移或者加载色彩参数
    叫显示器自己的硬件调节做好该做的
    做不好的垃圾玩意直接砸换新就好
    TrembleBeforeMe
        4
    TrembleBeforeMe  
       2022-04-14 10:01:38 +08:00
    目前的低价 HDR 显示器体验实在是不能说好
    mmdsun
        5
    mmdsun  
       2022-05-01 15:26:26 +08:00
    后来 WDDM 规范中加入了[矩阵变换作为可选功能]( https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/d3dkmddi/ns-d3dkmddi-_dxgk_colortransformcaps),但是并没有说明如何从用户态调用这个功能。在 Windows 11 SDK 中,微软提供了一个没有文档、甚至没有对应导出函数的 API 。

    这个文档 doc ,往最下面有个 github 连接,你去提 question 问就好了或者要求补充更详细文档。我之前调 WinUI3 框架,网上根本找不到类似资料,有问题直接去问,微软基本都秒回。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1150 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 17:46 PVG 01:46 LAX 09:46 JFK 12:46
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86