Alpha值的含义
对于 RGBA(或 BGRA )数据, Alpha 通道中存储的 Alpha 值,实际上应该是 Opaque 值,即不透明度。当 Alpha 值为 255 时,表示不透明; Alpha 值为 0 时,表示全透明。
Alpha 值也经常用 0 ~ 1 这个区间的数字来表示。 0 表示全透明, 1 表示不透明。详见这里:https://en.wikipedia.org/wiki/Alpha_compositing。
直接 Alpha 和预乘 Alpha 的区别
Alpha 模式有两种,直接 Alpha 和预乘 Alpha 。
使用直接 Alpha 描述 RGBA 颜色时,颜色的 Alpha 值会存储在 Alpha 通道中。例如,若要描述具有 60% 不透明度的绿色,请使用以下值:(0 , 255 , 0 , 255 * 0.6) = (0 , 255 , 0 , 153)。值 255 指示全绿, 153(255 的 60%)指示颜色应具有 60% 的不透明度。
使用预乘 Alpha 描述 RGBA 颜色时,每种颜色都会与 Alpha 值相乘:(0 * 0.6, 255 * 0.6 , 0 * 0.6 , 255 * 0.6) = (0 , 153 , 0 , 153)。同时 Alpha 值也会存储在 Alpha 通道中。
RGBA图像数据叠加
我只考虑一幅带 Alpha 效果的图像叠加在背景上的情况。
假设背景图像是 B ,无透明效果,带透明效果的图像是 A ,那么透过 A 去看 B ,看上去的图象 C 就是 A 和 B 的混合图象。
假设 A 图像的透明度为 alpha ,则图像 C 的混合公式如下:
R(C) = alpha * R(A) + (1 - alpha) * R(B)
G(C) = alpha * G(A) + (1 - alpha) * G(B)
B(C) = alpha * B(A) + (1 - alpha) * B(B)
A(C) = 1
混合后的图像 C 的Alpha值为 1 ,所以后面的代码里,直接将结果的 Alpha 值设置为 0xFF 。
————————————————
版权声明:本文为优快云博主「foruok」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/foruok/article/details/50785841
alpha混合技术对熟悉游戏的人来说不会陌生,这种技术在如今的游戏特效里已经被用烂了。3D的游戏就不说了,2D的游戏里,这种技术也是满眼皆是。
alpha混合听上去很神秘,实际非常简单,其作用就是要实现一种半透明效果。假设一种不透明东西的颜色是A,另一种透明的东西的颜色是B,那么透过B去看A,看上去的颜色C就是B和A的混合颜色,可以用这个式子来近似,设B物体的透明度为alpha(取值为0-1,0为完全透明,1为完全不透明)
R(C)=alpha*R(B)+(1-alpha)*R(A)
G(C)=alpha*G(B)+(1-alpha)*G(A)
B(C)=alpha*B(B)+(1-alpha)*B(A)
R(x)、G(x)、B(x)分别指颜色x的RGB分量。看起来这个东西这么简单,可是用它实现的效果绝对不简单,应用alpha混合技术,可以实现出最眩目的火光、烟雾、阴影、动态光源等等一切你可以想象的出来的半透明效果。
火光、烟雾的效果是事先做好一个火或雾的图和一个alpha通道图(用过Photoshop的人都该知道什么是alpha通道),画上去的时候每点每点计算,得到的就是火光掩映的效果。雾化效果在3D里还需要模糊一下,在这里就免了,本来alpha混合就有不小的计算量了,算法再不优化再加上模糊或其它的一些什么原因,那么你就是在看幻灯片了。(关于优化,网上见仁见智,我再找时候再讲)。
动态光源,听起来高深的一塌。那我先讲一下阴影,这个就简单了,以往的游戏也有阴影(象《仙剑》),不过我们把它升一下级,从不透明变成半透明而已。就是把一个影子图放在地表上面作alpha混合(而且可以简化,因为影子的alpha值可以是一定的,这样就可以大幅提高计算速度)就OK了。
该讲动态光源了。我们把没有光源的地方想象成一张黑幕蒙在屏幕上,没光也就什么都看不到。那么我们就加上一个光源,相当于在黑幕上挖了一个洞,这个洞的大小就是被照亮的范围,现在我们可以看到下面的东西了。但现在这个效果说是光源,倒不如说是个窗户,要显得象光源,就要让光源的中心最亮,逐渐向四周暗下去,最后到什么都看不见,这才象个光源。具体实现就是alpha混合啦,蒙版的颜色是黑,中心alpha值为0,完全透明,到光源的尽头alpha值为1,完全不透明,成果就是这个样子,象这么回事吧!光源做好了,动态的光源就是实时生成一个动态的alpha蒙版,然后盖上去就行了。
不难吧!游戏里(其实也不只游戏,好多算法也是这样)的一些技术听起来很玄,说通了也就是那么回事,只不过不是一下子就能想到就是了。
Diablo里面就大量应用了alpha混合技术(至少我看上去象),那些眩目的魔法产生出来的半透明效果,还有乱飞的火球照亮迷宫,每个火球也就是个小的光源,一堆光源产生出来的蒙版(就是对应的alpha相加,超过255就截断)再蒙上去。(真正的光源应该是这样的:当alpha值超过255时,alpha=alpha-255,alpha是一个Byte时也就是回绕,同时该点蒙版的色彩变为白色,这才是对的,不过简单起见,还是原来那样就可以了)。