OpenGL中混合(Blending)通常指的是实现物体透明度(Transparency)的一种技术。在RGBA里面采用的混合模型叫“Porter-Duff”模型,通过该模型可实现混合效果。这个模型的核心公式:
结果色 = 源色 原因子 + 目标色 目标因子。
结果alpha = 源透明度 源因子 + 目标透明度 目标因子。
- 源色即源颜色向量,这是源自纹理的颜色向量。
- 目标色即目标颜色向量,这是当前储存在颜色缓冲中的颜色向量。
- 源因子指定了alpha值对源颜色的影响程度。
- 目标因子指定了alpha值对目标颜色的影响程度。
源颜色和目标颜色将会由OpenGL自动设定,但源因子和目标因子的值可以有我们来决定。这个是一个混合的默认公式,使用glBlendFunc来实现。当然的在GL中还提供一些灵活的用法。
- 简单的Blending
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 开启Blend
glEnable(GL_BLEND);
// 使用默认的Blend公式来进行混合
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/**
* void glBlendFunc(GLenum sfactor, GLenum dfactor);
* 原因子和目标因子值及其含义:
* GL_ZERO = (0, 0, 0, 0)
* GL_ONE = (1, 1, 1, 1)
* GL_SRC_COLOR = (sR, sG, sB, sA)
* GL_DST_COLOR = (dR, dG, dB, dA)
* GL_ONE_MINUS_SRC_COLOR = (1 - sR, 1 - sG, 1 - sB, 1 - sA)
* GL_ONE_MINUS_DST_COLOR = (1 - dR, 1 - dG, 1 - dB, 1 - dA)
* GL_SRC_ALPHA = (sA, sA, sA, sA)
* GL_DST_ALPHA = (dA, dA, dA, dA)
* GL_ONE_MINUS_SRC_ALPHA = (1 - sA, 1 - sA, 1 - sA, 1 - sA)
* GL_ONE_MINUS_DST_ALPHA = (1 - dA, 1 - dA, 1 - dA, 1 - dA)
* GL_SRC_ALPHA_SATURATE = (i, i, i, 1 )
* /
分别设置RGB和Alpha混合因子系数的Blending
1
2
3
4
5
6
7
8
9
10// 开启Blend
glEnable(GL_BLEND);
// 分别设置RGB和Alpha
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);// 这个函数和我们之前设置的那样设置了RGB分量,但这样只能让最终的alpha分量被源颜色向量的alpha值所影响到。
/**
* 参数是RGB或者Alpha的混合因子
* void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
* /指定Blend公式的Blending
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 开启Blend
glEnable(GL_BLEND);
// 指定帧缓存区与源颜色混合的方式
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
// 允许RGB和Alpha使用不同的混合方式
glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
/**
* 可选混合公式
* GL_FUNC_ADD:默认选项,将两个分量相加,C = S + D
* GL_FUNC_SUBTRACT:将两个分量相减,C = S - D
* GL_FUNC_REVERSE_SUBTRACT:将两个分量倒置并相减,C = D - S
* GL_MIN:取分量小值,Rr=min(Rs,Rd) Gr=min(Gs,Gd) Br=min(Bs,Bd)
* GL_MAX:取分量大值,Rr=max(Rs,Rd) Gr=max(Gs,Gd) Br=max(Bs,Bd)
Demo工程:OpenGL学习实例
图像合成滤镜
假如我们不开启GL的混合的话,默认是不处理图片的Alpha通道的才导致了下图的这种情况。这时我们有几种处理方法:
- 假设背景是张Texture我们可以将两张Texture在着色器中使用Mix进行颜色混合。
- 无论背景是什么,我们在着色器中判断alpha < 0.1然后进行Discard把这个片段丢弃。
- 开启GL的混合模式。
下图是开启Blend模式的贴图: