Unity之透明度混合与ps的透明度混合计算结果不一致

一、问题

前段时间学习shader时发现了一个问题,一张纯红色透明度为128的图片叠加在一张纯绿色的图片上在unity中得出的结果与ps中的结果不一致。网上查找了ps中的透明混合的公式为 

color = A.rgb*A.alpha + B.rgb*(1-A.alpha)。自己使用代码在unity中计算了一下结果总是不对。 

红色透明度128的图                                          绿色图

                               

 ps中红色在上绿色在下叠加后的结果色

    

 Unity叠加后的结果色

二、原因及颜色空间描述

其主要原因是,unity使用的颜色空间(Color Space)为线性空间(Linear),而ps使用的是伽马空间(gamma)。使用Linear空间下不会对图片进行gamma矫正,所以Unity图片透明混合会比ps混合的图片亮度高。根据下方的描述可以理解为什么会出现这个问题。

1.伽马空间(gamma)。

网上搜索很多关于Gamma的文章看的最多的一句是人眼对光强的感知能力并不是线性的。这句话的意思是什么呢?下面根据图片解释一下这句话的意思。

这是一个黑白渐变图。在rgba数值中是(0,0,0,1)~(1,1,1,1)

根据上面这个图左侧黑色数值为0,右侧白色数值为1,那么半灰色是不是0~1区间的中间数0.5呢?在数学中0~1的中间值的确应该是0.5。但是人眼在自然界中看到的半灰色实际在上面这张图的3/4的位置即:0.75。来我们看下面这张图:

我们根据 “物理亮度图” 第0.5的半灰色对比去找 “人类自然界感知亮度图”中对应的颜色应该是在0.75左右。所以“ 人眼对光强的感知能力并不是线性的 ” 的意思就是如此。这句话也表明了通过伽马空间(gamma)计算矫正可以使 “物理亮度图” 和 “人类自然界感知亮度图”中的数值统一对应。

公式:L= 255 * ((R/255)^2.2)

gamma=2.2

红色的虚线是经过Gamma计算后矫正的屏幕亮度曲线,而对角连接的灰色虚线是人类感知亮度。伽马空间就是为了矫正我们屏幕中看到颜色让其与现实中人类感知颜色保持一致的。

在Unity中伽马空间中透明度混合公式: color = A.rgb*A.alpha + B.rgb*(1-A.alpha) 

2. 线性空间(Linear)

这个空间对应的就是物理空间亮度图。半灰色在0~1区间中属于正常的0.5。根据上方伽马空间描述了解到人眼感受的亮度值比实际物理空间的亮度值暗,所以unity中线性空间下的图片亮度会比gamma矫正后的图片要亮。

2.1Texture纹理图片sRGB(Color Texture)属性

Texture纹理图片sRGB(Color Texture)属性只有在线性空间下才管用。勾选是开启gamma矫正,未勾选是不开启gamma矫正。

在线性空间下勾选了sRGB效果图:

运算公式 color = (A.rgb^2.2 * A.alpha + B.rgb^2.2 * (1-A.alpha)) ^ (1/2.2)   

未勾选sRGB效果图:

运算公式 color = (A.rgb * A.alpha + B.rgb*(1-A.alpha)) ^(1/2.2)   

三、解决方法 

1.将unity改为伽马空间(gamma)

修改 File—>Build Settings—>Player Settings—>Other Setting选项卡中的Color Space为gamma即可。

2.PS修改为Linear 

 “编辑”—>“颜色设置”—>勾选“用灰度系数混合RGB颜色”。

 修改后ps的最后混合颜色结果 与unity中的一致。

猜你喜欢

转载自blog.csdn.net/qq_42345116/article/details/131342063