在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

= THE END =

一文详解 OpenGL ES 纹理颜色混合的更多相关文章

  1. 一文详解 OpenGL ES 3.x 渲染管线

    OpenGL ES 构建的三维空间,其中的三维实体由许多的三角形拼接构成.如下图左侧所示的三维实体圆锥,其由许多三角形按照一定规律拼接构成.而组成圆锥的每一个三角形,其任意一个顶点由三维空间中 x.y ...

  2. 详解 OpenGL ES 2.x 渲染流程

    khronos官方对OpenGL ES的描述如下: OpenGL ES is a royalty-free, cross-platform API for rendering advanced 2D ...

  3. 一文详解Hexo+Github小白建站

    作者:玩世不恭的Coder时间:2020-03-08说明:本文为原创文章,未经允许不可转载,转载前请联系作者 一文详解Hexo+Github小白建站 前言 GitHub是一个面向开源及私有软件项目的托 ...

  4. 一文详解 Linux 系统常用监控工一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)具(top,htop,iotop,iftop)

    一文详解 Linux 系统常用监控工具(top,htop,iotop,iftop)     概 述 本文主要记录一下 Linux 系统上一些常用的系统监控工具,非常好用.正所谓磨刀不误砍柴工,花点时间 ...

  5. 一文详解 纹理采样与Mipmap纹理——构建山地渲染效果

    在开发一些相对较大的场景时,例如:一片铺满相同草地纹理的丘陵地形,如果不采用一些技术手段,就会出现远处的丘陵较近处的丘陵相比更加的清晰的视觉效果,而这种效果与真实世界中近处的物体清晰远处物体模糊的效果 ...

  6. Android OpenGL ES 开发(九): OpenGL ES 纹理贴图

    一.概念 一般说来,纹理是表示物体表面的一幅或几幅二维图形,也称纹理贴图(texture).当把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实.当前流行的图形系统中,纹理绘制已经成为 ...

  7. OpenGL ES: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  8. 一文详解 WebSocket 网络协议

    WebSocket 协议运行在TCP协议之上,与Http协议同属于应用层网络数据传输协议.WebSocket相比于Http协议最大的特点是:允许服务端主动向客户端推送数据(从而解决Http 1.1协议 ...

  9. 1.3w字,一文详解死锁!

    死锁(Dead Lock)指的是两个或两个以上的运算单元(进程.线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁. 1.死锁演示 死锁的形成分为两个方面,一个是使用 ...

随机推荐

  1. C#中指针的使用(转)

    在C#中,有时候希望通过指针来操作内存,这样可以提高效率.我们可以用unsafe关键字修饰含有指针操作的程序段,如下所示: class Program {   static int Main(stri ...

  2. .NET 百万级 大数据插入、更新 ,支持多种数据库

    功能介绍  (需要版本5.0.44) 大数据操作ORM性能瓶颈在实体转换上面,并且不能使用常规的Sql去实现 当列越多转换越慢,SqlSugar将转换性能做到极致,并且采用数据库最佳API 操作数据库 ...

  3. [luogu7417]Minimizing Edges P

    令$e_{G}(a)$和$o_{G}(a)$分别表示在图$G$中从1到$a$的长度为奇数/偶数的最短路(若该类最短路不存在则为$\infty$),不难得到有以下结论--$f_{G}(a,b)=\beg ...

  4. 二、JAVA API实现HDFS

    目录 前文 hdfsdemo通过HDFS上传下载文件 windows环境下需要使用uitls.exe 为pom.xml增加依赖 新建java文件HDFS_CRUD GitHub下载地址 前文 一.Ce ...

  5. 六、Java API操作zookeeper节点

    目录 前文 pom.xml文件增加依赖 新建java文件:ZookeeperTest GitHub文件下载 前文 一.CentOS7 hadoop3.3.1安装(单机分布式.伪分布式.分布式 二.JA ...

  6. HashSet 如何保证元素不重复——hash码

    HashSet 不重复主要add 方法实现,使用 add 方法找到是否存在元素,存在就不添加,不存在就添加.HashSet 主要是基于HashMap 实现的,HashMap 的key就是 HashSe ...

  7. 同时在多个 Git 分支上工作,老板要榨干我

    背景 上一篇文章 保持清洁的Git提交记录,三招就够了 ,大家看过后有私下留言说这是非常好用的功能,我突然想到工作中用到的另外一个 Git 功能那也是相当好用,必须全盘托出 作为程序员的我们应该都有一 ...

  8. Mysql的delimiter

    告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令. 有时 ...

  9. hadoop基础题

    转自:http://blog.csdn.net/pelick/article/details/8299482 //Hadoop基础 Doug Cutting所创立的项目的名称都受到其家人的启发,以下项 ...

  10. Excel-满足指定条件并且包含数字的单元格数目,DCOUNT()

    DCOUNT函数 函数名称:DCOUNT 主要功能:返回数据库或列表的列中满足指定条件并且包含数字的单元格数目. 使用格式:DCOUNT(database,field,criteria) 参数说明:D ...