假定一个场景,在OpenGL中,我们需要在一张图层中添加一个透明度为30%的图层,这种情况我们应该怎么做呢?
image.png
如上图的这个例子,假如红色、绿色都是半透明的,叠在一起,为啥会出现这个情况?这个情况就是混合。
概念
混合是指两种颜色的叠加方式。通俗的讲,就是把某一像素位置上原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果。
如上图的例子,在A像素点原本是红色填充,现在有一个绿色的、半透明的图层要遮盖在上面,这个时候就需要开启混合,重新计算出新的颜色。
- 目标颜色,已经存储在颜色缓冲区的颜色值,比如图中的红色所代表的值。(这个目标与我们通常理解的目标有出入,不要混淆)
- 源颜色,作为当前渲染命令结果进入颜色缓冲区的颜色值,比如图中新加入的绿色所代表的值。
- 混合方程式,当开启混合时,源颜色和目标颜色的组合是方程式控制的。如下:
//Cf :最终计算参数的颜⾊
//Cs : 源颜⾊
//S:源混合因⼦
//Cd :⽬标颜⾊
//D:⽬标混合因⼦
Cf = (Cs * S) + (Cd * D)
设置混合因子,需要用到glBlendFunc函数:
//S:源混合因⼦
//D:⽬标混合因⼦
glBlendFunc(GLenum S, GLenum D);
函数 | 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) | Ad |
GL_ONE_MINUS_DST_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_DST_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 |
表中R、G、B、A 分别代表 红、绿、蓝、alpha。
表中下标S、D,分别代表源、⽬标
表中C 代表常量颜⾊(默认⿊⾊)
举个例子,我们用以下这个公式,
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
还是拿上图来说,目标颜色是红色(1.0,0.0,0.0,1.0),源颜色是半透明的绿色(0.0,1.0,0.0,0.5),那么公式如下:
Cd(目标颜色) = (1.0,0.0,0.0,1.0);
Cs(源颜色) = (0.0,1.0,0.0,0.5);
S = 源Alpha值 = 0.5f;
D = 1 - 源alpha值= 1-0.5f = 0.5f
Cf = (红色 * 0.5f) + (绿色 * 0.5f)
用法
- 开启混合
//1.开启混合
glEnable(GL_BLEND);
//2.开启组合函数 计算混合颜色因子
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- 关闭混合
//关闭混合
glDisable(GL_BLEND);
网友评论