【Unity3D日常开发】Unity3D的Color Space(颜色空间)【全解析】
先放一张图感受一下:在Unity打包选项中,有一个Color Space的选项,有Gamma和Linear两个选项。主要作用是设置Unity是否对输入的默认贴图进行转换处理,法线贴图不存在这个问题。Gamma时,Unity不会在后台将图片进行转换,输入的即使是经过矫正的图片,Unity也不会处理,比如Remove Gamma Correction去除伽马校正Gamma Correction伽马校正
推荐阅读
大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
一、前言
Edit→Player Settings→Other Settings→Rendering→Color Space(颜色空间)
先放一张图感受一下:
在Unity打包选项中,有一个Color Space的选项,有Gamma
和Linear
两个选项。
主要作用是设置Unity是否对输入的默认贴图进行转换处理,法线贴图不存在这个问题。
Gamma
时,Unity不会在后台将图片进行转换,输入的即使是经过矫正的图片,Unity也不会处理,比如Remove Gamma Correction去除伽马校正
、Gamma Correction伽马校正
都不会发生,除非自己手动实现。
Linear
时,Unity就会进行统一线性空间的流程,也就是Gamma Correction
,对于sRGB纹理,Unity 会利用GPU对图片进行采样,剔除矫正Remove Gamma Correction
,转换到线性空间,然后再传给Shader处理,处理后的图片会再加上Gamma矫正
,再显示在屏幕上。
简而言之就是Gamma
不会对输入和输出进行处理,Linear
会对sRGB纹理进行剔除矫正,转换到线性空间,再传给Shader处理
。
那接下来,我们就来了解一下Gamma和Linear的原理,以及支持Linear颜色空间的纹理类型,还有支持线性空间的硬件和特性。
二、正文
2-1、纹理与Linear
Unity在导入贴图的导入设置面板中sRGB(Color Texture)选项,勾选它,告诉Unity这是一张sRGB贴图,需要对sRGB编码才可以获得用于光照计算的数据,不勾选,表示这是一张线性贴图,这张贴图的颜色数据可直接用于光照计算。
当然,除了sRGB(Color Texture)选项,其他的类型,比如Normal Map、Light Map都是Linear,设置好类型Unity自己会处理它们。
那什么时候才会用到sRGB贴图呢?
比如在导出贴图时,会对提供色彩信息的贴图,比如Albedo和Specular Color做sRGB编码,这样做的目的是为了让贴图看起来更舒服,更符合人眼感知的方式。
所以,这种情况就可以导出sRBG贴图来使用。但是对于法线贴图、金属度贴图这类用于存储数值信息的贴图,是不做sRBG编码的,所以就当线性贴图来使用。
2-2、什么是sRGB
上述说的解码Gamma
只是理想状态下机制。
然而每一台显示器的解码值Gamma值并不统一,会导致同一张图片再不同的显示器上看起来不一样。
解决方案是引入Color Profile(色彩配置文件),也就是RGB数值与颜色波长之间的对应关系。
图片都再带有一个Color Profile,显示器收到这个文件后,根据显示器自己的Color Profile后转换为屏幕输出该特定波长所需的RGB值。
也就是说Color Profile既有波长这个量值,也有Gamma矫正。
sRGB是一种最常见的Color Profile,是微软联合惠普等厂商联合制定的色彩标准。
sRGB色彩空间就是Gamma色彩空间。
2-3、硬件特性支持
主要由两个硬件特性来支持:
sRGB Frame Buffer
- 将Shader的计算结果输出到显示器前左gamma校正
- 作为纹理被读取时会自动把存储的颜色从sRGB空间转换到线性空间
- 调用ReadPixels()、readBackImage()时,会直接返回sRGB空间下的颜色
- sRGB Frame Buffer只支持每通道8bit的格式,不支持浮点格式
- HDR开启后会先把渲染结果绘制到浮点格式的FB中,最后绘制到sRGB FB上输出
sRGB Sampler - 将sRGB的贴图进行线性采样的转换
- 使用硬件特性完成sRGB贴图的线性采样和shader计算结果的gamma校正,比起在shader里对贴图采样和计算结果的校正要快。
2-4、线性空间 Linear Space
在现实世界中,光的强度增加一倍,那么亮度也会增加一倍,这是线性关系。
为了保证数学上准确,光照计算应该在线性空间执行,意即sRGB格式的输入值需要先做sRGB解码——在贴图的导入设置面板中有**sRGB(Color Texture)**选项。
如果勾选开启sRGB,那么在采样时会自动对采样得到的值进行sRGB解码。
此外还设置有一个sRGB格式的buffer,GPU会在shader写入color buffer前自动进行sRGB编码。
这里用到了两个底层图形API:sRGB Sampler和sRGB Frame Buffer。
(如果unity使用Gamma颜色空间,sRGB的设置是无效的,因为贴图总是会被线性采样。)
sRGB (Color Texture)设置的意义:这应该总是检查非hdr颜色纹理(如反照率和高光颜色)。如果纹理存储具有特定含义的信息,并且您需要在着色器中获得准确的值(例如,平滑度或金属),请取消选中此框。默认情况下选中此框。
实际在unity 中取消勾选sRGB后图片会变亮,我觉得实际可能是下面这样:(不勾选sRGB的图片会被编码为sRGB格式)
sRGB只对RGB通道有效,对alpha通道无效
alpha值不参与任何编码gamma、解码gamma的计算,它直接进入shader,被shader读取;
以MetallicSmoothness贴图为例,存储在Alpha通道的Smoothness,本来就是线性的,不论贴图勾不勾选sRGB,都不会影响它,shader能正确读取它的值。
2-5、Gamma和Linear的优缺点
Linear线性色彩空间
Linear线性色彩空间是一种更接近显示光线传播的标识方式,使用线性关系来处理颜色。
在Linerar线性色彩空间中,颜色值的变化更加准确和自然,能够实现更真实世界的光照效果。
Gamma伽马色彩空间
Gamma伽马色彩空间是一种更符合人眼感知的方式,使用非线性关系来处理颜色。
在Gamma伽马色彩空间中,颜色值的变化更加符合人眼的感知特性,能够更好地呈现对比度和亮度等方面的内容。
总结一下
对于需要更真实光照效果的项目,使用Linear线性色彩空间会更合适。默认颜色空间是Gamma伽马色彩空间。
所有需要人眼参与被创作出来的纹理,都应是sRGB(如美术画出来的图)。
所有通过计算机计算出来的纹理(如噪声,Mask,LightMap)都应是Linear。
这很好解释,人眼看东西才需要考虑显示特性和校正的问题。
而对计算机来说不需要,在计算机看来只是普通数据,自然直接选择Linear是最好的。
三、后记
如果觉得本篇文章有用别忘了点个关注,关注不迷路,持续分享更多Unity干货文章。
你的点赞就是对博主的支持,有问题记得留言:
博主主页有联系方式。
博主还有跟多宝藏文章等待你的发掘哦:
专栏 | 方向 | 简介 |
---|---|---|
Unity3D开发小游戏 | 小游戏开发教程 | 分享一些使用Unity3D引擎开发的小游戏,分享一些制作小游戏的教程。 |
Unity3D从入门到进阶 | 入门 | 从自学Unity中获取灵感,总结从零开始学习Unity的路线,有C#和Unity的知识。 |
Unity3D之UGUI | UGUI | Unity的UI系统UGUI全解析,从UGUI的基础控件开始讲起,然后将UGUI的原理,UGUI的使用全面教学。 |
Unity3D之读取数据 | 文件读取 | 使用Unity3D读取txt文档、json文档、xml文档、csv文档、Excel文档。 |
Unity3D之数据集合 | 数据集合 | 数组集合:数组、List、字典、堆栈、链表等数据集合知识分享。 |
Unity3D之VR/AR(虚拟仿真)开发 | 虚拟仿真 | 总结博主工作常见的虚拟仿真需求进行案例讲解。 |
Unity3D之插件 | 插件 | 主要分享在Unity开发中用到的一些插件使用方法,插件介绍等 |
Unity3D之日常开发 | 日常记录 | 主要是博主日常开发中用到的,用到的方法技巧,开发思路,代码分享等 |
Unity3D之日常BUG | 日常记录 | 记录在使用Unity3D编辑器开发项目过程中,遇到的BUG和坑,让后来人可以有些参考。 |
更多推荐
所有评论(0)