博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

alpha混合原理

Posted on 2013-01-31 17:37  RUI2021  阅读(822)  评论(0编辑  收藏  举报

绘制图形的颜色总是替换当前颜色缓冲区中存在的颜色,这样后面的物体总是覆盖在原有的物体上。但是当想要绘制类似于玻璃、水等具有透明效果的物体时,这种方法显然满足不了要求。通过定义一个表示物体半透明度的alpha值和一个半透明计算公式,可以将要绘制的物体颜色与颜色缓冲区中存在的颜色相混合,从而绘制出具有半透明效果的物体。Direct3D计算alpha颜色混合的方法如下:

color = (RGBsrc * Ksrc) OP (RGBdst * Kdst)

其中color表示alpha混合后的颜色值,RGBsrc表示源颜色值,即将要绘制的图元的颜色值;Ksrc表示源混合系数,通常赋值为表示半透明程度的alpha值,也可以是属于枚举类型D3DBLEND的任意值,用来和RGBsrc相乘。RGBdst表示目标颜色值,即当前颜色缓冲区中的颜色值,Kdst表示目标混合系数,可以是属于枚举D3DBLEND的任意值,用来和RGBdst相乘。OP表示源计算结果与颜色缓冲区计算结果的混合方法,默认状态下OP为D3DBLEND_ADD,即源计算结果与颜色缓冲区计算结果相加。

图形显示中,对alpha混合最普遍的用法是:把Ksrc赋值为D3DBLEND_SRCALPHA,即当前绘制像素的alpha值;把Kdst赋值为D3DBLEND_INVSRCALPHA,即1减去当前绘制像素的alpha值;把OP赋值为D3DBLEND_ADD,使源计算结果和颜色缓冲区计算结果相加,这样一来,alpha混合颜色的公式变为:

color = (RGBsrc * Ksrc) + (RGBdst * Kdst)

上面的设置可以较好地模拟大多数半透明物体的效果。

由于alpha混合是当前绘制的像素颜色与颜色缓冲区中存在的颜色的混合运算,因此,在绘制半透明物体前,必须保证位于半透明物体后的物体先于半透明物体绘制,也就是说,先绘制不透明物体,再绘制半透明物体。


alpha源混合系数通常设置为D3DBLEND_SRCALPHA,即当前绘制像素的alpha值。目标混合系数设置为D3DBLEND_INVSRCALPHA,即1减去当前绘制像素的alpha值。那么当前绘制像素的alpha值又是如何得到的呢?如果没有使用材质和纹理,当前绘制像素的alpha值来自每个顶点颜色设置的alpha值;如果使用光照和材质,则当前像素的alpha值来自物体表面材质;如果为物体表面使用了纹理,则alpha值还与纹理有关。

 

顶点alpha
如果在程序中直接指定每个顶点的颜色,则可以直接给出每个顶点颜色的 alpha值,可以在定义顶点时直接声明该顶点的alpha值,也可以在程序运行时动态地修改顶点的alpha值。有了顶点的alpha值,渲染对象中每个像素的alpha值由该对象的alpha值和着色模式决定。当着色模式为FLAT着色模式时,构成对象的各个多边形中所有像素的alpha都等于该多边形的第一个顶点的alpha值。当着色模式为GOURAUD着色模式时,每个多边形面上的像素的alpha值由它的各个顶点的alpha值进行线性插值得到的。

 

材质alpha
顶点alpha是没有使用光照和材质的情况,如果对场景内的物体添加光照和材质而没有添加纹理时,顶点alpha值取决于材质属性中漫反射颜色的alpha系数和灯光颜色中的alpha系数,顶点alpha值是根据光照计算得到的。顶点光照计算是分别针对红、绿、蓝和alpha进行的,其中alpha光照计算的结果就是顶点的alpha值。有了顶点的alpha值就可根据着色模式计算出每个像素的alpha值,第一个示例程序就是材质alpha的例子。

 

纹理alpha
当对物体表面使用了纹理之后,像素的alpha值就是纹理alpha混合之后的值,所以这又取决于纹理的alpha混合方法,纹理alpha混合方法决定了纹理alpha混合之后的alpha值是取自材质,还是取自纹理,或者取自二者的某种运算。像素alpha值的具体计算过程是这样的,首先得到顶点alpha值,顶点alpha值可能是直接指定的,也可能是光照计算得到,然后根据着色模式对顶点alpha值进行插值,得到的结果再根据纹理alpha混合方法和纹理采样得到的alpha值进行指定的运算,得到最终每个像素的alpha值。

 

alpha测试
alpha测试根据当前像素是否满足alpha测试条件(即是否达到一定的透明度)来控制是否绘制该像素,图形程序应用alpha测试可以有效地屏蔽某些像素颜色。与alpha混合相比,alpha测试不将当前像素的颜色与颜色缓冲区中像素的颜色混合,像素要么完全不透明,要么完全透明。由于无需进行颜色缓冲区的读操作和颜色混合,因此alpha测试在速度上要优于alpha混合。