伽马空间和线性空间的区别和作用

线性空间

​ 在物理世界中,光强增加一倍亮度也增加一倍,呈线性关系,物理世界中的颜色和光照规律都是在线性空间描述的。计算机图形学是物理世界视觉的数学模型,Shader中颜色插值、光照的计算自然也是在线性空间描述

伽马空间

​ 伽马空间实际是对RGB的数值进行一次Pow操作,如果是Pow(x,0.45)则为Gamma0.45空间,也可称之为伽马矫正如果是Pow(x,2.2)则为Gamma2.2空间,也可称之为逆伽马矫正,一次伽马一次逆伽马叠加正好是线性空间结果

​ 由于人眼对于亮度变化的感知不是线性的,对于暗色调更敏感,我们应该用更大的数据范围来寸暗色调,用较小的数据范围存亮色调,对于这个需求,可以观察到Gama0.45的曲线是符合的,然后在显示器这边对输入的信号进行一次逆伽马矫正,这样最终显示结果是真实的线性空间表现,颜色存储是按Gamma0.45进行的。

材质的空间

​ 当前业界中常用的sRGB格式就是存储在Gamma0.45空间的,Unity中sRGB的勾选应该选上。而NormalMap、噪声、Mask、LightMap等其他计算出来的纹理则一般在线性空间,在Unity中sRGB的勾选应该去掉。对于Shader中的颜色输入,Unity也视为Gamma0.45空间,变量则为线性空间,如果要让变量变为Gamma0.45空间,则需要在变量前加上[Gamma]


Unity中的线性空间工作流

​ 在Unity中,我们在Player Setting中可以看到有伽马空间和线性空间两种选择。

​ 如果选择伽马空间,Unity不会对材质进行处理,如果是sRGB,Shader中的数据就是Gamma0.45中的数据,如果要转到线性空间进行PBR计算需要手动写代码将其进行转换并在计算完后转回Gama0.45空间,但如果是线性空间的材质且没有在Shader中手动进行处理,在经过逆伽马的处理后会出现偏暗的不真实感觉,该空间的好处主要是减少了部分计算,但是对于PBR的计算处理会比较复杂,如果不需要PBR计算的话可以考虑选择该空间。

​ 如果选择线性空间,Unity会根据材质的类型自动判断是否进行Remove Gamma Correction,也就是逆伽马矫正,保证Shader中的计算都是在线性空间,并且会自动对Shader计算结果进行伽马矫正,最后显示器进行逆伽马矫正,让呈现到玩家的是线性空间的真实世界,这样做的好处是保证了Shader的计算是在线性空间,减少了Shader代码的复杂,这也要求项目组美术,TA,渲染工程师的工作空间都在线性空间,这也是目前大多数项目的选择。