修正 NVIDIA 显卡 HDMI 色彩输出

此处输入图片的描述

HDMI 作为一种通用的信号,广泛的用于电视以及娱乐系统领域,不像 DVI 和 DP 接口那样,是专为计算机显示器来设计的。所以当 PC 端的显卡通过 HDMI 接口连接 PC 显示器的时候,就会出现一些令人不爽的小问题。


常见的 3 个基本色彩模型分别是:

  • RGB
  • CMYK
  • YUV

YCbCr 有时也称为 YCC,而 YCC 不是一种绝对色彩空间,而是 YUV 压缩和偏移的版本。YCbCr 是计算机系统中应用最多的成员,其应用领域很广泛。JPEG,MPEG 均采用此格式,一般人所讲的 YUV 大多是指 YCbCr
YCbCr 有多种取样格式,比如:

  • 4:4:4
  • 4:2:2
  • 4:1:1
  • 4:2:0
    Y:
    明亮度 (Luminancr 或 Luma),也就是灰阶值。「亮度」是透过 RGB 输入信号来建立,方法是将 RGB 信号的特定部分叠加在一起。
    U&V:
    色度(Chrominance 或 Chroma),作用是描述影像色彩饱和度,用于指定像素的颜色,「色度」则定义了颜色的两个方面——色调和饱和度,分别用 CrCb 表示。
    Cb:
    反映的是 RGB 输入信号蓝色部分与 RGB 信号亮度值之间的差异。
    Cr:
    反映了 RGB 输入信号红色部分与 RGB 信号亮度值之间的差异。

在以下的两个公式中 RGB 和 YCbCr 各分量的范围均为 0-255
Y = 0.299R + 0.587G + 0.114B
U = -0.1687R - 0.3313G + 0.5B + 128
V = 0.5R - 0.4187G - 0.08313B + 128

R = Y +1.402(U-128)
G = Y - 0.34414(U-128)-0.71414(V-128)
B = Y + 1.772(U-128)

灰阶明暗等级的表现。
HDMI 传输数字色差信号常采用 YPbPr8 位数字 RGB 信号的话,是 RGB 三通道各 8 位,总计 24 位的形式来传输。8 位能表现 0-255 个层次,0最暗255

例如:

  • (255.255.255) 最亮的白
  • (0.0.0) 黑色

但电视(TV)和影像领域的视频信号是通过色差信号表示的,电视使用 IRE 规格:
纯黑 IRE 0%
纯白 IRE 100%
Y = 235 即灰阶表现范围为 16-235

投影仪和电视产品默认输入信号范围为 16-235,而 HDMI 输入信号范围的 0-255 直接输入的话,就会出现暗部过暗,而亮部又太亮的问题。
PC 显示器等默认输入范围是 0-255 ,直接输入范围 0-235 的信号的话,现象就会反过来。比如说,出现黑色变为深灰而不是纯黑色,白色变为浅灰。
对应的相关现象表格如下:
(O 代表正常)

显示设备(HDMI 出端)表示机器(HDMI 入端)效果
RGB = 0 - 255RGB = 0-255O
RGB = 16 - 235RGB = 0 - 255不正常
RGB = 0 - 255RGB = 16 - 235不正常
RGB = 16 - 235RGB = 16 - 235O
—-———-
Y = 16 - 235Y = 16-235O
Y = 16 - 255Y = 16-235不正常
Y = 16 - 235Y = 16-255不正常
Y = 16 - 255Y = 16-255O

NVIDIA 的 GPU 是如何处理 HDMI 信号的?

当显卡通过 HDMI 连接线或者是 DVI 转 HDMI 接口连接到显示器的时候, GPU 会默认将显示器识别为 HDTV而不是 PC 显示器

此处输入图片的描述

在 NVIDIA 控制面板的分辨率设置界面上,可以清楚的看到 GPU 默认将其识别成了 HDTV,同时列表里还有一些譬如超清 Ultra HD,高清 HD,以及标清 SD 等选项可调。
但是如果你通过 DP 或是 DVI 接口连接上显示器的话,你会发现情况有些不同了,GPU 默认将其识别成了 PC 显示器

此处输入图片的描述
同样也有些分辨率可调,也可输出 1080P (1920x1080)


那么问题来了?

仅仅是简单的识别错误而其它都一切正常吗?

正如开头时所说,通过 HDMI 接口连接显卡,GPU 默认输出了
‘Limited Range RGB’ ——有限范围的 RGB 信道 16-235
而不是
‘Full Range RGB’——全范围的 RGB 信道 0-255

电视(TV)和影像领域的视频信号是通过色差信号表示的,电视使用 IRE 规格,
纯黑 IRE 0%
纯白 IRE 100%
Y = 235 即灰阶表现范围为 16-235

投影仪和电视产品默认输入信号范围为 16-235,而 HDMI 输入信号范围的 0-255 直接输入的话,就会出现暗部过暗,而亮部又太亮的问题。
PC 显示器等默认输入范围是 0-255 ,直接输入范围 0-235 的信号的话,现象就会反过来。最简单的例子就是出现黑色不纯,变为深灰而不是真正的纯黑色。白色也不是纯白而是变为淡淡的浅灰。


第一个解决方法:

自定义分辨率设置

此处输入图片的描述
通过 NVIDIA 控制面板中的「自定义分辨率」手动设置分辨率,创建完成后,就可以在面板列表里面看到新创建的分辨率。
而这种方法对并不是对所有的桌面和应用程序都奏效,有些游戏以及其他程序会自动忽略用户自定义的分辨率设置,转而去使用系统的默认配置。

第二个解决方法:

更改数字颜色格式为 YCbCr444
此处输入图片的描述

更改数字颜色格式为 YCbCr444,是一个非常简单避免「色彩浪费」的方法,通过 切换数字颜色格式为 YCbCr444 GPU会将默认的 Limited Range RGB 输出更改为另一种近 Full Range RGB 的色彩表现形式来输出信号,以下是基本的参数对比,从中可以看出,使用 YCbCr 输出的方式与 Full Range RGB 的输出类似,但是还是有一些区别的。

此处输入图片的描述

通过第三方工具修改强制性进行 Full Range RGB 输出:

推荐使用 NV_RGBFullRangeToggle 进行修改,原理是通过修改显卡驱动中的相关注册项来强制实现 Full Range RGB 的输出,不过副作用就是:
因为是在驱动中临时更改的所以每次安装新的驱动时,还需重新的运行工具来进行相关的修改

事实上,制造 PC 显示器的厂商一般会设计一套自动识别的功能,但是识别结果貌似不是太友好,有时会出现识别不准的情况,所以就得手动的进行相关设置和调教,以获得最佳显示效果。

尾巴:

事实上,如果有心留意 NVIDIA 推送的驱动的话,会发现 NVIDIA 自从 347.09 beta 版驱动开始,就已经在 NVIDIA 控制面板中的色彩设置里官方地引入了 更改动态范围的设置。
也许 NVIDIA 也意识到使用 HDMI 在 PC 显示器上输出 Full range RGB 在的重要性。

无「民事行为能力」人慎点