OpenGL(6)——颜色混合

154 阅读4分钟

上面文章介绍了OpenGL的深度测试,我们知道如果有多个图层重叠时,当打开深度缓冲区时,OpenGL只会把距离观察者较近的图层绘制出来。如果上面的图层是非透明的,这样做没有问题。但是如果上面的图层的颜色是半透明的呢?是不是还只是显示上层的图层呢?这显然是不行的。正常来讲,应该是显示上层图层的半透明色和下层图层的颜色的混合色。但是OpenGL不会自动帮我们完成这样的混合,需要我们手动开启颜色混合。下面就讲一下OpenGL是如何做的。

1.开启/关闭混合

跟开启深度测试类似,调用glEnable函数,传入GL_BlEND参数,就可以打开颜色混合了。

//开启
glEnable(GL_BlEND);
//关闭
glDisable(GL_BLEND);

2.混合

2.1 混合方程式

在介绍混合方程式之前先介绍两个定义:目标颜色和源颜色。

  • 目标颜色:已经存储在颜色缓冲区中的颜色。
  • 源颜色:作为当前渲染命令结果进入颜色缓冲区的颜色值。

当混合功能被启动时,源颜色和目标颜色的组合方式是由混合方程式控制的。在默认情况下混合方程式如下所示:

Cf = (Cs * S) + (Cd * D)

Cf :最终计算参数的颜⾊
Cs : 源颜⾊
Cd :⽬标颜⾊
S : 混合因⼦
D : ⽬标混合因⼦

通过方程式可以看出,根据混合因子的不同,最终的混合结果也是不同的。那可我们如何设置混合因子呢?

2.2 混合因子

设置混合因子,需要用到glBlendFun函数:

glBlendFunc(GLenum S,GLenum D);

S:源混合因⼦
D:目标混合因子

可以看出混合因子的类型是GLenum,是一个枚举类型,枚举值列表如下:

枚举值 RGB混合因子 Alpha混合因子
GL_ZERO (0,0,0) 0
GL_ONE (1,1,1) 1
GL_SRC_COLOR (Rs,Gs,Bs) As
GL_ONE_MINUS_SRC_COLOR (1,1,1)-(Rs,Gs,Bs) 1-As
GL_DST_COLOR (Rd,Gd,Bd) As
GL_ONE_MINUS_DSL_COLOR (1,1,1)-(Rd,Gd,Bd) 1-Ad
GL_SRC_ALPHA (As,As,As) As
GL_ONE_MINUS_SRC_ALPHA (1,1,1)-(As,As,As) 1-As
GL_DSL_ALPHA (Ad,Ad,Ad) Ad
GL_ONE_MINUS_DST_ALPHA (1,1,1)-(Ad,Ad,Ad) 1-Ad
GL_CONSTANT_COLOR (Rc,Gc,Bc) Ac
GL_ONE_MINUS_CONSTANT_COlOR (1,1,1)-(Rc,Gc,Bc) 1-Ac
GL_CONSTANT_ALPHA (Ac,Ac,Ac) Ac
GL_ONE_MINUS_CONSTANT_ALPHA (1,1,1)-(Ac,Ac,Ac) 1-Ac
GL_SRC_ALPHA_SATURATE (f,f,f)* f=min(As,1-Ad) 1

表中R、G、B、A 分别代表 红、绿、蓝、alpha。
表中下标S、D,分别代表源、⽬标。
表中C 代表常量颜色(默认⿊色)。

2.3 案例

下面通过一个例子,来讲解混合因子的使用

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

如果颜⾊缓存区已经有了目标颜⾊红色(1.0f,0.0f,0.0f,0.0f)。源颜色是不透明度为0.6的蓝色0.0f,0.0f,1.0f,0.6f)。
Cd (⽬标颜⾊) = (1.0f,0.0f,0.0f,0.0f);
Cs (源颜色) = (0.0f,0.0f,1.0f,0.6f);
D = 1 - 源alpha值 = 1-0.6f = 0.4f
S = 源alpha值 = 0.6f

套用公式:

Cf = (Cs * S) + (Cd * D)

等价于

cf = (Blue * 0.6f) + (Red * 0.4f)

最终颜⾊是以原先的红色(⽬标颜色)与 后来的蓝色(源颜色)进⾏组合。源颜⾊的alpha值越高,添加的蓝颜⾊成分越高,⽬标颜⾊所保留的成分就会越少。

混合函数经常⽤于实现在其他⼀些不透明的物体前绘制⼀个透明物体的效果。

2.4 更换组合方程式

除了使用默认的组合方程式,我们还可以通过函数指定其他的方程式来进行颜色混合。

glbBlendEquation(GLenum mode);

下表列举了OpenGL提供的枚举值:

模式 方程式
GL_FUNC_ADD CF = (Cs * S) + (Cd * D)
GL_FUNS_SUBTRACT CF = (Cs * S) - (Cd * D)
GL_FUNS_REVERSE_SUBTRACT CF = (Cs * D) - (Cd * S)
GL_MIN CF = min(Cs,Cd)
GL_MAX CF = max(Cs,Cd)

2.5 分开设置混合因子

在使用glBlendFunc设置混合因子时,RGB混合因子Alpha混合因子是绑定到一起的 。我们还可以使用glBlendFuncSeparate来更加灵活的设置。

void glBlendFuncSeparate(
GLenum strRGB, GLenum dstRGB, GLenum strAlpha, GLenum dstAlpha);

strRGB: 源颜⾊的混合因子
dstRGB: ⽬标颜色的混合因子
strAlpha: 源颜⾊的Alpha因子
dstAlpha: ⽬标颜色的Alpha因子

2.6 更换常量颜色

在混合因子表中GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_ALPHAGL_ONE_MINUS_CONSTANT 值允许混合⽅程式中引⼊一个常量混合颜色。
常量混合颜色,默认初始化为⿊色(0.0f,0.0f,0.0f,0.0f),但是还是可以修改这个常量混合颜色。

void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );