在正常情况下,OpenGL渲染时会把颜色值输入到颜色缓冲区中,深度值输入到深度缓冲区中。如果我们关闭深度测试,那么新的颜色值会简单地覆盖已经存在于颜色缓冲区中的值。当开启深度测试时,颜色段只有在通过深度测试时,才会覆盖已经存在于颜色缓冲区中的值。在这两种情况下,在渲染时颜色值要么完全被废弃,要么就直接覆盖旧的颜色值。现在介绍一种新的方式,混合。
glEnable(GL_BLEND);
当开启混合时,输入的颜色值将会和已经存在于颜色缓冲区中的颜色进行组合。至于如何进行组合,取决于你为混合设置的参数。
?
首先需要了解两个概念:
当开启OpenGL的混合时,源颜色是如何与目标颜色进行结合的,取决于你设置的混合方程式。默认情况下的,混合方程如下:
Ci = (Cs * S) + (Cd * D)
在这里,Ci是最终被计算出来的颜色,Cs是源颜色,Cd是目标颜色。而S和D分别是源混合因子和目标混合因子。这些混合因子通过:glBlendFunc(GLenum S, GLenum D);设置。S和D是枚举值,其枚举列表如下:(R、G、B、A分别代表红色成分,绿色成分,蓝色成分,Alpha成分)
?
* f = min(A s , 1 – A d)
PS:上面表格的颜色值都是用浮点数来表示的。举例说明:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
通过上面的调用来告诉OpenGL我们使用的混合因子。假设现在渲染命令传进来的源RGBA颜色值是(1.0f,0.0f,1.0f,1.0f).而在颜色缓冲区相同的位置已经有目标颜色RGBA值是(0.0f, 1.0f, 0.0f, 1.0f).
代入公式:Ci = (Cs * S) + (Cd * D)
Cs=(1.0f,0.0f,1.0f,0.6f), GL_SRC_ALPHA参数说明源混合因子取源颜色的alpha值,所以 S = 0.6f。Cd=(0.0f, 1.0f, 0.0f, 1.0f). GL_ONE_MINUS_SRC_ALPHA说明了目标混合因子取1-As,D = 1-0.6 = 0.4f;
所以代入计算得(Cs * S) = (0.6f, 0.0f, 0.6f, 0.36f) , (Cd * D) = (0.0f, 0.4f, 0.0f, 0.4f)
Ci = (Cs * S) + (Cd * D) = (0.6f, 0.4f, 0.6f, 0.76f)
得到的颜色是近似于洋紫色。
上面表格的GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,GL_CONSTANT_ALPHA和GL_ONE_MINUS_CONSTANT_ALPHA的值在默认情况下是(0.0f, 0.0f, 0.0f, 0.0f)但我们可以通过下面的函数修改:
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
颜色混合经常用于在不透明的前面画一个透明的物体。这样我们就可以先画好背景,然后再在上面画一个半透明的物体。可以制造一种,透过彩色玻璃看外面的风景的效果。下面的例子:(物体在光滑的彩色地面上的倒影)。

?
OpenGL的默认混合方程式:Ci = (Cs * S) + (Cd * D)
但我们可以通过函数:
void glBlendEquation(GLenum mode);
来改变混合方程。可选择的混合方程模式如下表:

还有一个更灵活的函数:
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
这个函数允许你分别指定RGB的混合方程和alpha成分的混合方程。