Part12 混合

        所谓的混合就是将两种图元的颜色按照某种规则混合产生一种新的颜色的效果。在OpenGL当中可以看到表示一个顶点的颜色我们使用的是一种称之为RGBA的颜色表示方案,在这种颜色表示方案当中前面三个分量RGB与通常使用的颜色表示方案相同,而最后一个分量称之为alpha分量。alpha这个单词在photoshop等等的图形设计软件当中经常可以看到,在OpenGL当中alpha这个单词的解释与这些设计软件当中的解释几乎完全相同,即alpha指的是图元的不透明度,所谓的不透明度就是说如果alpha的值为0.5那么有一半的光可以透过图元射到后面与之重合的图元当中。
        在没有使用混合之前的OpenGL程序当中往往使用3个分量的颜色函数来表示顶点的颜色,这种3个分量的颜色表示实际上是将顶点颜色的alpha值设置为1,也就是完全不透明。而事实上在使用混合之前各个定点颜色RGBA值当中的alpha值实际上是完全没有用处的。但是在混合当中就需要用的alpha值了。
        在混合当中原本存在于帧缓存当中的当前像素的RGBA值称之为目标颜色,而要绘制到帧缓存当中片元对应像素的RGBA值称为源颜色。在使用混合之前,如果绘制一个片元OpenGL要做的工作实际上是比较深度缓存当中这个像素的深度与要绘制进来片元对应像素的深度,如果要绘制进来的像素在帧缓存像素之前,那么绘制新的像素,并且更新深度缓存当中的值。而使用混合以后(通常意义上使用混合就需要关闭深度缓存,这样需要注意的是绘制片元的顺序总是从里面到外面)OpenGL要做的工作就是根据已经提供的混合函数以及源颜色和目标颜色计算新的混合颜色并且保存到帧缓存当中去。计算新颜色的公式如下:
R = Rs × Ds op Rd × Dd 
G = Gs × Ds op Gd × Dd 
B = Bs × Ds op Bd × Dd 
A = As × Ds op Ad × Ad 
这里可以看到两个参数Ds和Dd,这两个参数就是我们设置的一个混合函数,通常设置混合函数我们调用OpenGL函数glBlendFunc来实现,这个函数需要两个参数分别表示Ds和Dd两个的值。举个例子,假如说在一个物体之前有一块有色的半透明的玻璃,那么因为深度缓存关闭的原因我们需要先绘制物体,然后绘制玻璃,假设说玻璃是蓝色的,由于是半透明的那么他的RGBA值就是(0,0,1,0.5),为了达到玻璃的半透明效果,我们就要使用混合,在这个例子当中就要调用glBlendFunc(GL_SRC_ALPHA,GL_SRC_ONE_MINUES_ALPHA);
这里两个参数的意义是:
GL_SRC_ALPHA:D = As   也就是说使用源颜色的各个分量乘以源颜色的ALPHA值
GL_SRC_ONE_MINUS_ALPHA:Dd = 1-As 用目标颜色乘以源颜色ALPHA值与1的值
这样得到的颜色正好是符合半透明的实际效果,至于混合函数其他参数的意义可以参考MSDN的说明。
        另外我们可以看到混合方程当中还有一个操作符op,这个操作符在默认情况下为+,但是我们可以通过函数glBlendEquation来改变它。
        所以通过上面的说明我们可以总结出使用混合的方法是
1.关闭深度测试,打开混合(glEnable(GL_BLEND)),设置混合函数(glBlendFunc)
2.从里到外依次绘制片元
        上面所讲到的混合方法在场景当中所有物体的深度顺序较为简单和有顺序时比较有效,但是如果说场景当中模型的深度很复杂,并且有些物体是不透明的会完全遮挡住后面的物体,而有些物体是透明的需要使用混合时,如果还是用上面的办法来处理就比较复杂并且容易出错了。在这种情况下一般采用这样一种解决方案,首先绘制不透明物体,然后再绘制那些透明的需要混合处理的物体,并且即使在绘制这些需要混合处理的物体时也不关闭深度缓存,而只是将深度缓存设置为不可写(用glDepthMask(FALSE)函数调用来实现),这样的话如果绘制片元时OpenGL发现其靠近眼坐标的位置上有不透明物体那么就不绘制透明物体,否则就是用混合方式来绘制透明物体。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值