线性空间(Linear Space)与伽马空间(Gamma Space)
什么是线性空间?
线性空间中的颜色值、光照计算等都是直接按照物理世界的线性关系来处理的。在线性空间中,亮度的增加是均匀的,即如果亮度翻倍,那么实际显示出的亮度也会翻倍。
什么是伽马空间?
由于人眼对黑白敏感的程度不一致,对暗部的敏感度更高,加之于早期的CRT显示器输出的颜色亮度要比实际的数值要低,为了使人眼看起来正确,所以存储使用的颜色空间是非线性的,往往暗部占用更多的存储空间,伽马空间就是非线性空间的一种,在存储时会将亮度提高,显示时会将亮度压暗以还原真实人眼应该看到的颜色,这个过程被称作伽马校正。
什么是伽马校正?
- 存储时使用Gamma-correction函数将原始颜色调亮,这个函数一般是\(x^\frac{1}{2.2}\)
- 显示时使用Gamma-decode函数将调亮后的颜色还原,这个函数一般是\(x^{2.2}\)
伽马空间的公认标准称为 sRGB。sRGB定义了伽马空间与线性空间之间的一个映射,使得人眼能充分利用 8 位/通道的精度。伽马和线性颜色空间同时存在的原因是,光照计算应该在线性空间中进行,以便确保数学上的正确性,结果在伽马空间中呈现以便让人眼看起来正确,且在伽马空间下的存储精度更高。
线性(Linear)与伽马(Gamma)工作流程
在Unity中,提供了线性和伽马两种工作流程,可以在Edit-->Project Settings-->Player-->Rendering-->Color Space中进行选择。
若选择伽马工作流程,Unity不会对Shader的输入输出做任何处理,即便是这些值在伽马空间中,所有的Shader仍然按照线性空间的方式处理输入,并且Unity不会对最终的结果应用伽马校正。
若选择线性工作流程,当纹理模式为sRGB时,GPU硬件(sRGB Sampler)将纹理采样的颜色转换到线性空间(Remove Gamma Correction)后输入Shader中,若纹理模式不是sRGB则跳过转换,当完成着色工作后,GPU会在Shader写入颜色缓冲区前自动进行伽马校正或保持线性在后续中进行伽马校正。
根据美术制作纹理的方式选择其是否为sRGB模式
参考
颜色空间
Unite 2018 | 浅谈伽玛和线性颜色空间
Gamma、Linear、sRGB 和Unity Color Space
Gamma and Linear Space - What They Are and How They Differ