前置:OpenGL基础45:光照矫正(下)之Gamma校正_Jaihk662的博客-CSDN博客
一、Gamma 理论总结
在讲解这篇文章之前,需要先了解什么是 Gamma 空间和线性空间,也就是前置里的内容
当然这里也可以进行一个总结:
- 显示器的输出在 Gamma2.2 空间,这对应着
(GammaToLinear)
- 伽马校正 (LinearToGamma) 即是将颜色转换到 Gamma0.45 空间(sRGB对应的空间),对应
,伽马校正和显示器输出平衡之后,正好结果就是 Gamma1.0 的线性空间
- 所有的输入,计算和输出都统一在线性空间中,才能得到最真实的效果。但是这没有错和对,哪怕你不统一空间,能得到一个还算可以的效果也是没有问题的,甚至还更省性能
![](https://img-blog.csdnimg.cn/20210404173541376.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0phaWhrNjYy,size_16,color_FFFFFF,t_70)
关于 Linear Texture 和 sRGB Texture
我们拿到的一手纹理,哪些是线性空间(Gamma1.0)下的,又有那些是 sRGB(Gamma0.45) 空间下的呢?
- 一般可以确定美术输出资源时都是在 sRGB(Gamma0.45)空间的,例如漫反射纹理、环境光纹理等:这些 RGB 通道直接作为颜色参考的,需要人眼参与被创作出来的纹理
- 而电脑计算出来的程序纹理则是在线性空间(Gamma1.0)中的,例如噪声纹理、法线纹理等
如何告诉 Unity 这个纹理是否处于线性空间:
如果你设置了特殊的 Texture Type,例如 Normal Map 和 Light Map,那么 Unity 就会知道这张纹理是线性空间下的,否则需要留意这个属性:
勾上之后,Unity 就会知道这张纹理是在 sRGB 空间下的了,所以对于噪声纹理、Mask 纹理这些就千万不要勾
二、Unity 中的色彩空间(Color Space)
在 Project Settings 里可以告诉 Unity 你使用的空间
- Gamma:Unity 不会对 sRGB 纹理的输入和输出做任何处理
- Linear:Unity 会自动帮你做统一线性空间的流程,对于 sRGB 纹理,Unity 在进行纹理采样之前(传递到着色器时)会自动进行 Gamma 矫正移除,对于 Linear 纹理则没有这一步;而在输出前,Unity 也会自动进行 Gamma 矫正。除此之外,Shaderlab 中的颜色输入也会被认为是 sRGB 颜色,从而自动进行 Gamma 矫正移除
需要注意的是:对于 Android 系统,Linear 只在 OpenGL ES 3.0 和 Android 4.3 以上支持,IOS 则只有 Metal 才支持
[Gamma] 前缀
[Gamma] _Metallic("Metallic", Range(0, 1)) = 0
Shaderlab 属性(Properties) 前面使用 [Gamma] 标注,可以让一个 Float 变量也进行 Gamma 矫正移除,前提是告诉 Unity 你使用 Linear 空间
参考文章: