假设:
有一张半透明图片A,颜色通道为CA,不透明度为AA (范围:0-1)
一张半透明的图片B,颜色通道为CB,不透明度为AB (范围:0-1)
一张不透明的底图C,颜色通道为CC,不透明度为AC = 1
结果图D,颜色通道为CD,不透明度为AD。
B 盖在 C 上,记作 B blend C
则最终的颜色D = A blend ( B blend C )
1.先计算 B blend C,已知AB == 0 即 B图 全透明时,颜色为CC,
AB == 1,即 B图 不透明时,颜色为 CB
混合结果为不透明
所以,可以简单的 B blend C = { CB * AB + CC * (1 - AB), 1}
同理:
A blend ( B blend C ) = { CA * AA + CB*AB*(1-AA) + CC*(1-AB)*(1-AA),1}
为了证明混合支持交换律,就要证明 (A blend B) blend C == A blend (B blend C)
记:E = A blend B
要使 E blend C = A blend (B blend C),观察到,CD表达式里面CC的系数为(1-AB)*(1-AA)
E blend C = {CE*AE + CC*(1-AE),1}
联想到E blend C,CC的系数相等,所以,AE = 1 - (1-AB)*(1-AA) 则:
E = {(CA * AA + CB*AB*(1-AA)) / AE, AE}
那么,只要两个半透明的图片混合使用这个公式,就满足结合律了:
A Blend B = {(CA * AA + CB*AB*(1-AA)) / AE, AE} (AE = 1 - (1-AB)*(1-AA))
接着,研究一下这个公式
两个半透明的图片混合之后的不透明度
AE = 1 - (1-AB)*(1-AA) = AA + AB - AA*AB >= AA或AB(只有当AA或者AB透明度为0的时候取等号)
这里可以看出:
两张半透明的图片,混合之后的透明度,是要小于之前的任意一张的透明度的,
混合后的透明度(1-不透明度)=两张半透明图片的透明度的乘积,且与谁在前无关
再看混合后的颜色与对应图层的关系,图层B对最终颜色的影响,主要是
CB * AB *(1-AA) ,即 自身颜色*自身透明度 * 前面所有图层混合后的透明度,前面所有图层混合后的透明度降为0时,后面混合的颜色,对总的颜色,都没有影响
由于argb不透明度,a的取值在0-255,所以,混合255张半透明的图片,透明度必定降为0,这样,在3维渲染时,理论上,保存256张带深度的不透明的图片,最后渲染时合成一整张图片,就能实现无序透明度混合(解决opengl渲染半透明时,开启深度测试的情况下,远处物体,被近处半透明物体遮挡裁掉了,导致混合之后看不到远处物体)。
对于1920*1080的rgba图片(不包含深度),需要8M内存,如果255层就是2G显存,目前实现不了...