unity的颜色空间

unity的颜色空间Gamma和Linear

介绍

  • 人眼观察到的颜色不是线性的,为了使人眼感觉到线性的颜色变化,需要对颜色进行伽马校正
  • Gamma校正的公式为 Cl = pow(Cg,Y) ,Cl 是线性颜色(取值0-1),Cg 是Gamma颜色,Y 是Gamma值,显示设备的 Gamma 值为 2.2,因此 Gamma 颜色转线性是会变暗的
  • 显示设备接收的是经过Gamma校正的的电信号,即使是新的数字设备也沿用该习惯
    除了显示设备,图片和视频保存的颜色也是伽马校正过的
  • 伽马的颜色空间叫做 sRGB

为什么要用线性空间

因为 Gamma 颜色是为了符合人眼习惯而进行校正的,但在光照等需要对颜色进行运算时使用 Gamma 颜色是不准确的,所以需要先转换到线性空间,计算后在显示前再还原到 Gamma 空间

unity对线性颜色的支持

  • 素材的颜色空间
    美术提供的贴图一般是Gamma空间的,但法线和深度一般是线性空间的
    在导入纹理到unity中时,如果是Gamma空间则勾选 sRGB ,否则不勾选
    这样unity就知道素材的颜色空间
  • unity内部的颜色空间
    • PlayerSettings -> OtherSettings -> ColorSpace 可以选择 Gamma 或 Linear
    • 当你切换颜色空间时,unity会马上对素材进行处理,转成对应的颜色空间,而不是运行时再处理,提高运行效率,比如 纹理勾选 sRGB,ColorSpace设为Linear,则要对纹理进行转换,保存在缓存中
  • shader对颜色空间的处理
    • 我们在shader中获取的像素颜色就是unity颜色空间下的颜色,因此最好在项目开始时就要确定颜色空间,因为会影响shader的编写,一般建议用 Linear 空间
    • shader中可以用 UNITY_COLORSPACE_GAMMA 和 #ifndef UNITY_COLORSPACE_GAMMA 宏来编写不同颜色空间下的代码
    • shader中可以用unity提供的函数转换颜色空间
      • 线性转伽马 col.rgb = LinearToGammaSpace(col.rgb);
      • 伽马转线性 col.rgb = GammaToLinearSpace(col.rgb);
  • URP对颜色空间的处理
    如果选择 Linear 的颜色空间,则URP会在 FinalBlitPass 中把颜色转成 Gamma 空间后再上屏
  • 截屏或录屏对颜色空间的处理
    如果unity设为Linear的颜色空间,则获取的纹理中的颜色都是线性空间,此时如果是自己保存的话,必须先转成Gamma颜色空间,因为正常的图片和视频都是保存为Gamma空间
    可以观察录制的结果,太暗是没有做LinearToGamma 的转换,太亮则是多做了LinearToGamma的转换

unity使用线性颜色空间常见问题

  • android原生端提供的相机纹理通常是Gamma空间,如果在unity中渲染需要转成线性空间
    可以在 RawImage 上直接挂个Gamma转Linear的材质最方便
  • 保存成视频通常是 Gamma 空间,从unity把纹理传给 android 录制,需要转成 Gamma 空间

猜你喜欢

转载自blog.csdn.net/qmladm/article/details/142372180