Correcting HDMI colour on Nvidia GPU

此处输入图片的描述

你可能听人们说过,
HDMI (High-Definition Multimedia Interface)DP 接口(Display Port)以及 DVI (Digital Visual Interface)的显示效果相同,它们都是数字信号

事实并非如此,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

For example :

  • (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 控制面板中的「自定义分辨率」手动设置分辨率,创建完成后,就可以在 Pannel 列表里面看到新创建的分辨率。
而这种方法对并不是对所有的桌面和应用程序都奏效,有些游戏以及其他程序会自动忽略用户自定义的分辨率设置,转而去使用系统的默认配置。

####曲线救国方法二:
更改数字颜色格式为 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 在的重要性。
Anyway,厂商在设置面板里面添加的一项人性化小举措,就能让消费者以及受众用户节省很多不必要的繁琐操作,最重要的是时间,尤其是对一些相关专业知识了解微之甚微的用户来说,这简直无比的重要。
能在本该实现的功能上,做到操作上的删繁就简;而又不缺失整体的功能细节,做到返璞归真。
才是这个时代所需要的。

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