在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合。例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到OpenGLES混合
。
如上图所示,为石头墙、绿色矩形、蓝色云彩 三个矩形混合后的展示效果。三个矩形(Z轴深度由深到浅)分别为,石头墙、绿色矩形、蓝色云彩。
一、混合API
在OpenGLES中若使用混合,需要用到API函数方法(Java):void glBlendFunc( int srcfactor, int destfactor );
(1) 其OpenGL函数原型为: void glBlendFunc(GLenum srcfactor, GLenum destfactor);
(2) 其功能为:
控制新画上来的颜色 (source values, RGBA)
和 已经在帧缓冲区中的颜色 (destination values, RGBA)
的混合时源与目标 在最终颜色通道中所占的比例
。
(3) 方法参数
-
srcfactor:代表源因子,即新画上来的颜色。
该参数由九个枚举型被接受使用:
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_SRC_ALPHA_SATURATE. -
destfactor:代表的是目标因子,即已经在帧缓冲区中的颜色。
该参数由八个枚举型被接受使用:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
二、参数含义
- 举个栗子
- 参数含义
2.1 举个栗子
我们先看一个常用混合参数搭配:
// 最常用的混合因子搭配方式
// 即源因子为 GL_SRC_ALPHA 目标因子为 GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA);
以上参数搭配方式假设:
-
(Sr, Sg, Sb, Sa)
代表源颜色src(要绘制的颜色)
; -
(Dr, Dg, Db, Da)
代表目标颜色Dest(缓冲区中颜色)
如果源因子的不透明度为0.2(透明度0.8),alpha值的最大值为1,那么源与目标混合后的最终颜色值
为:
// 最终颜色值为:0.2*S+0.8*D
// OpenGL ES 最终颜色计算结果如下:
(0.2*Sr+(1-0.2)*Dr , 0.2*Sg+(1-0.2)*Dg , 0.2*Sb+(1-0.2)*Db,0.2*Sa+(1-0.2)*Da)
启用混合与纹理矩形绘制顺序代码举例:
// 开启混合
gl.glEnable(GL10.GL_BLEND);
// 指定混合比例
gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// 绘制石头墙纹理矩形
gl.glPushMatrix();
gl.glTranslatef(-0.8f, -0.8f, -0.02f);
wallRect.drawSelf(gl, tex_wall);
gl.glPopMatrix();
// 绘制绿色纹理矩形
gl.glPushMatrix();
gl.glTranslatef(0, 0, -0.01f);
greenRect.drawSelf(gl, tex_green);
gl.glPopMatrix();
// 绘制蓝色云彩纹理矩形
gl.glPushMatrix();
gl.glTranslatef(0.8f, 0.8f, 0f);
cloudRect.drawSelf(gl, tex_cloud);
gl.glPopMatrix();`
2.2 参数含义
有了上边的例子,我们再回来看各个参数因子。
假设:
-
(Sr, Sg, Sb, Sa)
代表源颜色src(要绘制的颜色)
; -
(Dr, Dg, Db, Da)
代表目标颜色Dest(缓冲区中颜色)
; -
(Kr, Kg, Kb, Ka)
代表缓冲区中各个通道R, G, B, A的最大值。
那么各个参数因子所代表的值如下表所示:
混合因子 | 各颜色通道色彩比例值 |
---|---|
GL_ZERO | (0,0,0,0) |
GL_ONE | (1,1,1,1) |
GL_SRC_COLOR | (Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka) |
GL_DST_COLOR | (Dr/Kr, Dg/Kg, Db/Kb, Da/Ka) |
GL_ONE_MINUS_SRC_COLOR | (1,1,1,1) - (Sr/Kr,Sg/Kg,Sb/Kb,Sa/Ka) |
GL_ONE_MINUS_DST_COLOR | (1,1,1,1) - (Dr/Kr,Dg/Kg,Db/Kb,Da/Ka) |
GL_SRC_ALPHA | ( Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka ) |
GL_ONE_MINUS_SRC_ALPHA | (1,1,1,1) - (Sa/Ka,Sa/Ka,Sa/Ka,Sa/Ka) |
GL_DST_ALPHA | ( Da/Ka, Da/Ka, Da/Ka, Da/Ka ) |
GL_ONE_MINUS_DST_ALPHA | (1,1,1,1) - (Da/Ka,Da/Ka,Da/Ka,Da/Ka) |
GL_SRC_ALPHA_SATURATE | (min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,1) |
三、 几种常用混合方式效果
下边以三张纹理图片在不同混合因子设置下的效果图,对几种常见的混合效果进行举例说明。
- 其中
离摄像机最远
的为一张Alpha=1.0
的石头墙
纹理图; - 其次 为一张
Alpha=0.6
的蓝色云彩
纹理图; - 最后
离摄像机最近
的为一张Alpha=0.4
的绿色纹理图。
3.1 混合(GL_ONE, GL_ZERO)
源颜色(最后绘制的绿色矩形)参数因子为GL_ONE,目标色(缓冲区中颜色)参数因子为GL_ZERO。
这种参数因子组合混合比例 (1.0, 0.0)
:
- 源颜色(最后绘制的绿色矩形)覆盖目标色(缓冲区中颜色);
- 目标色(缓冲区中颜色)不起作用,
其运行效果如下图所示:
3.2 混合(GL_ONE, GL_ONE)
源颜色(最后绘制的绿色矩形)与 目标色(缓冲区中颜色)均为GL_ONE。
这种参数因子组合混合比例 (1.0, 1.0)
:
-
源颜色(最后绘制的绿色矩形)
与目标色(缓冲区中颜色)
在混合时,源与目标的色彩通道颜色所占的比例相同
。
其运行效果如下图所示:
仔细观察以上效果图,可以看到三张图片叠加部分,几乎为白色。
3.3 混合(GL_ONE, GL_ONE_MINUS_DST_ALPHA)
源颜色(最后绘制的绿色矩形)参数因子为 GL_ONE,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_DST_ALPHA。
这种参数因子组合混合比例 (1.0, 1.0-Da/Ka)
:
-
源颜色(最后绘制的绿色矩形)
与目标色(缓冲区中颜色)
,在混合时取源颜色
与(1- Da/Ka)比例
进行混合。
其运行效果如下图所示:
观察以上效果图:可以看到最上边绿色矩形占最终混合颜色的比例较高。
三张纹理绘制时:
- 前两张纹理混合时:源颜色为
蓝色云彩纹理矩形
,目标颜色为石头墙纹理矩形
。
由于混合比例为 (1.0, 1.0-Da/Ka),混合后的最终颜色只显示蓝色云彩纹理矩形
(石头墙纹理的ALPHA=1.0,最终石头墙颜色所占的比例 1.0-1.0=0.0,比例为0)。 - 其次
绿色纹理矩形
与缓冲区中颜色
进行混合:源颜色为绿色纹理矩形
,目标颜色为缓冲区中颜色
。
混合后的最终颜色基本只显示绿色纹理矩形
(蓝色云彩纹理矩形的ALPHA=0.6,(1-0.6)云纹理与绿色矩形混合后,几乎看不到云纹理的颜色)。
3.4 混合 (GL_SRC_ALPHA, GL_ONE)
源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE。
这种参数因子组合混合比例 (Sa/Ka, 1.0)
:
-
源颜色(最后绘制的绿色矩形)
与目标色(缓冲区中颜色)
,在混合时以源颜色值乘以Sa/Ka与目标颜色值相加。
其运行效果如下图所示:
观察以上效果图,可以看出目标墙面与云纹理混合后墙面纹理颜色值所占比例较高,三个纹理图片叠加部分有些像素点为白色。
3.5 混合 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
这种方式是最常用的混合方式,源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_SRC_ALPHA。
这种参数因子组合混合比例 (Sa/Ka, 1.0-Sa/Ka)
:
-
源颜色(最后绘制的绿色矩形)
与目标色(缓冲区中颜色)
在混合时,取源颜色的 (Sa/Ka) 与目标颜色 (1.0-Sa/Ka) 相加计算最终的颜色值。
其运行效果如下图所示:
附案例代码
案例源码下载地址:
https://download.csdn.net/download/aiwusheng/64038379