颜色空间

颜色空间

线性空间和伽马空间

线性空间下,我们感知到的强度和对应的数值强度是按比例对应的,也就是说如果有两个数值强度0.25和0.25那么他们相加的数值强度就是0.5。

使用线性空间,是因为光照计算的需要,只有使用线性空间才能在数学上正确计算出光照

而使用伽马空间,一是因为显示器对颜色强度的感知是非线性的,另一个原因是人眼在较暗的环境下比起亮的环境能够更好的辨别细节。

因此在图像压缩中我们希望能够在暗部获得更高的精确度,所以对图像每个像素引入了一个幂函数来进行处理,

使用RGB来表示颜色的时候,一般用0到255的整数或者0到1之间的小数

线性空间和伽马空间,实质上是对同一颜色在不同标准下的记录

假设有一种灰色,在线性空间下表示为0.5,0.5,0.5​,在伽马空间下,这个颜色则表示为0.73,0.73,0.73​,但实际上,它们是同一种颜色

大多数图像在存储时都应用了 0.45 的伽马系数,这将产生如上左图所示的效果。现在,图像的较暗区域使用更大的值范围进行记录,而明亮范围则被压缩。以这种方式存储的图像位于 “gamma 空间” 中。

例如,图像中的中性灰色的数值强度不是 0.5,而是在 0.73 左右,而纯白色和黑色保持不变。这是几乎所有数码相机以及图像编辑应用程序等的默认行为。事实上,您在计算机上看到的几乎每张图像都应用了该灰度系数。

为什么图像显示正确,而看起来不会太亮。这就是显示器非线性响应的用武之地。CRT 屏幕,仅从它们的工作原理来看,应用大约 2.2 的伽玛系数,而现代 LCD 屏幕旨在模仿这种行为。当伽玛 2.2(0.45 的倒数)应用于增亮的图像时,会使它们变暗,留下原始图像。

例如,左上图表示计算机上存储的内容,显示后,结果将类似于中心图像。左侧图像已经过“伽马系数校正”,这意味着它具有伽马系数值,因此在将屏幕的伽马系数应用于图像后,它将正确显示。

如果计算机存储的是尚未经过 Gamma 校正的中心图像,则显示的结果看起来就像正确的图像,这显然是不需要的行为​​

问题

在实习的时候,遇到了一点UI和场景中颜色空间的问题。​​

在项目中,场景使用的是线性空间,而UI使用的是伽马空间,场景计算完成后,会转换为伽马空间,同UI一保持一致,然后经由显示器矫正

因为相框是使用MeshRenderer组件显示在场景中的,而选择时查看的图片是在UI上

由于场景中要进行正确的光照计算,所以使用的是线性空间,而UI上的图片使用的是伽马空间,自定义的渲染管线会再后面将场景的颜色空间从线性空间再变换为伽马空间,以求和UI同步后进行后续处理

而直接将UI上Image组件的sprite(这个sprite实际上是原图,从kresource.load加载来的)传给MeshRenderer的sprite时会有色差,因此在MeshRenderer上使用UIInScene材质进行颜色矫正,将sprite从伽马空间变换到线性空间,以便和场景同步

参考

线性空间和伽马空间 | ZY-Zhang (crunchybiscuits.github.io)


颜色空间
https://enlight3n.github.io/2024/08/29/UnitySummary/颜色空间/
作者
Enlight3n
发布于
2024年8月29日
许可协议