Unity3D Gamma And Linear Space

参考:https://www.cnblogs.com/murongxiaopifu/p/9001314.html

总结:

1. CRT gamma 和 gamma correction

 

上图中的红色实心线是在gamma = 2.2的情况下,显示器实际显示色彩强度的方式。 这一部分是由显示器的特性导致的。所以如果图片不做任何处理,经过pow(2.2)的操作之后显然会变得更暗,所以gamma校正就显得很有必要了。而gamma校正要做的事情也十分简单,即通过pow(1/2.2)将颜色强度提高,也就是上方的红色虚线,这样经过显示器时就会将显示器的pow(2.2)抵消掉。

CRT gamma 是显示器做的,pow(x,2.2),x=[0,1],变暗

gamma correction 是为了抵消 CRT gamma 而做的,pow(x,1 / 2.2), x=[0,1], 变亮

2.  gamma空间下的纹理格式和FrameBuffer格式

a. 无论 纹理 是否勾选了 sRGB (Color Texture) 选项,纹理格式都是不变的,例如都是 GL_COMPRESSED_RGB8_ETC2

b. framebuffer 格式  GL_RGBA8

3. linear 空间的下的纹理格式和FrameBuffer格式

a. 纹理 勾选了 sRGB (Color Texture) 选项,纹理格式 GL_COMPRESSED_SRGB8_ETC2,而且纹理变暗了,它被作为一张sRGB纹理来看待,在传入Shader的之前,会对texture进行pow(x,2.2),将输入从sRGB空间转换到线性空间,保证数据是线性的。硬件会对其作一次Pow2.2的gamma校正,将它转化到线性空间中.

b. 纹理 没有勾选了 sRGB (Color Texture) 选项,纹理格式 GL_COMPRESSED_RGB8_ETC2。而且纹理没有变化,直接把纹理的数据当成是线性。硬件不会对它进行pow2.2的gamma校正操作

c. framebuffer的格式为GL_SRGB8_ALPHA8, framebuffer保存数据是 经过了pow(x,1 / 2.2) 的gamma校正过的,硬件做的,就是从线性空间转换到了sRGB空间——这当然是合理的,因为它要中和最后显示器的gamma校正。也就是说,srgb的framebuffer保存的就是 srgb格式的数据。

3. 透明混合

由于透明混合是一个线性的过程,因此在混合中作为Dst的那一方的framebuffer的数据就要是线性空间的了。
所以此时混合的操作事实上会先将framebuffer的内容从sRGB空间再次pow2.2转换到线性空间,和src进行混合,再将混合后的结果pow0.45(pow(x,1 / 2.2))转换回sRGB空间保存到framebuffer中

在Linear Space 中的混合:

ret = (srcColor^2.2 * srcAlpha + dstColor^2.2 * (1 - srcAlpha) ) ^(1/2.2)

在gamma Space 中的混合:

ret = srcColor * srcAlpha + dstColor * (1 - srcAlpha)

4. 注意

这里需要注意,Alpha通道是不会参与伽马校正的,只是RGB。

猜你喜欢

转载自blog.csdn.net/aa20274270/article/details/84954179