Gama校正

颜色空间

颜色范围差不多,主要区别是传递函数不同。

传递函数

将空间下三原色的值转换成视频信号 。包含两部分:OETF(光转电传递函数),EOTF(电转光传递函数)。即gama校正使用的函数。

Gama校正

 指对线性三色值和非线性视频信号之间进行编码和解码的操作。

图像经过gamma编码存储在硬盘中,将获取到的物理数据做一次gamma值约为0.45的映射,这样的过程叫做gamma编码。由曲线可知,此时图像的像素比实际物理像素要更亮。在显示图像时,需要将每个像素做一次gamma值约为2.2的矫正使最终的结果为正确的物理数据。经过显示的gamma校正之后,之前偏亮的图像亮度降低。

为什么用非线性的方式存储信号:

非线性转换的目的主要是为了优化存储空间和带宽,传递函数能够更好地帮我们利用编码空间。由于我们用于显示图像数据都是8bit,且人眼对暗部变化更敏感,如果要充分利用带宽,那么就需要使用更多位置去存储暗部值。也就是说暗部使用更高精度保存,而亮部使用更低精度保存。

将自然界线性增长的亮度灰阶变化和心理感受的灰阶变化做一个映射,就可以得到gama编码曲线。

韦伯定律:即感觉的差别阈限随原来刺激量的变化而变化,而且表现为一定的规律性,用公式来表示,就是△φ/φ=C, 其中中为原刺激量,△φ为此时的差别阈限,C为常数,又称为韦柏率。
简单来说就是,当所受刺激越大时,需要增加的刺激也要足够大才会让人感觉到明显变化,但是只适用于中等强度的刺激。

1.人眼对暗部变化比亮部更加敏感
2.我们目前所使用的真彩格式RGBA32,每个颜色通道只有8位用于记录信息,为了合理使用带宽和存储空间,需要进行非线性转换。
3.目前我们所普遍使用的sRGB颜色空间标准,他的传递函数gamma值为2.2(2.4)

 中灰值并非一个固定的具体数值,而是取决于视觉感受。

线性工作流

在各个环节正确的使用gamma编码/解码,来达到最终输出的数据和最初输入的物理数据一致的目的。

如果使用Gamma空间的贴图,在传给着色器之前需要从Gamma空间转到线性空间。目的是在着色器中做一些渲染计算时会使用线性空间的颜色值,这样就不会出现一些显示错误的结果。

如果不在线性空间下进行渲染操作:亮度叠加时会出现过曝效果,而颜色混合时会在纯色的边界出现黑边。

Unity中的颜色空间

通过点击菜单Edit->Project Settings->Player页签->Other Settings下的Rendering部分进行修改,参数Color Space可以选择Gamma或Linear

当选择Gamma Space时,Unity不会做任何处理;
当选择LinearSpace时,引擎的渲染流程在线性空间计算,理想情况下项目使用线性空间的贴图颜色,不需要勾选sRGB,如果勾选了sRGB的贴图,会通过硬件特性采样时进行线性转换。 

硬件支持

线性空间需要图形API的硬件支持,目前支持的平台
1. Windows, Mac OS X和Linux(Standalone)
2. Xbox One
3.PS 4
4. Android (OpenGL ES 3.0)
5.iOS(Metal)
6. WebGL

硬件特性支持

主要由两个硬件特性来支持:

  • sRGB Frame Buffer

➢将Shader的计算结果输出到显示器前做Gamma校正
➢作为纹理被读取时会自动把存储的颜色从sRGB空间转换到线性空间
➢调用ReadPixels()、 ReadBacklmage()时 ,会直接返回sRGB空间下的颜色
➢sRGB Frame Buffer只支持每通道为8bit的格式,不支持浮点格式
➢HDR开启后会先把渲染结果绘制到浮点格式的FB中,最后绘制到sRGBFB_上输出。

  • sRGB Sampler

➢将sRGB的贴图进行线性采样的转换。

使用硬件特性完成sRGB贴图的线性采样和shader计算结果的gamma校正,比起在shader里对贴图采样和计算结果的校正要快

资源导出问题

Substance Painter:当Substance的贴图导出时,线性的颜色值经过伽马变换,颜色被提亮了,所以需要在Unity中勾选sRGB选项,让它在采样时能还原回线性值。

Photoshop:如果使用线性空间,一.般来说Photoshop可以什么都不改,导出的贴图只要勾sRGB就可以了。如果调整PhotoShop的伽玛值为1,导出的贴图在Unity中也不需要勾选sRGB了

相关讲解视频:Gamma校正与线性工作流入门讲解_哔哩哔哩_bilibili 

猜你喜欢

转载自blog.csdn.net/weixin_51327051/article/details/123051939