OpenGL ES 高级进阶:颜色混合

你们好,这是个人OpenGL ES 高级进阶系列文章,在个人github上有一个与本系列文章对应的项目,欢迎关注,连接:github.com/kenneycode/…html

今天给你们介绍OpenGL的颜色混合,什么是颜色混合呢?颜色混合就是把两种颜色按某种规则混合起来获得新的颜色,来看一张图:git

好比咱们两种颜色颜色,一种是纯蓝色ARGB(255, 0, 0, 255),一种是纯绿色ARGB(255, 0, 255, 0),混合时分别各取一半,就获得了混合后的颜色ARGB(255, 0, 127, 127),这就是颜色合混的基本概念。github

那么何时须要用到颜色混合?咱们来看一种最多见的状况,咱们把一张带有透明部分的纹理渲染到另外一张纹理上,会怎样?spa

你们可能会说,这不是很显然吗?透明部分会把底图透出来,但若是你在OpenGL里不使用颜色混合直接渲染,你会发现结果是这样的:3d

透明部分并无把底图透出来,这是为何呢?由于颜色混合默认是关闭的,当没开启颜色混合时,把一个颜色渲染到另外一个颜色上,新的颜色就会把原颜色彻底覆盖,从而获得一个alpha为0的颜色,透出了最底层的黑色。code

咱们来看看如何用颜色混合来解决这个问题,首先须要开启颜色混合:cdn

// 启用颜色混合
// Enable color blend
GLES30.glEnable(GLES30.GL_BLEND)
复制代码

还须要设置混合方式,所谓混合方式的就是指定源颜色(将要渲染的颜色)和目标颜色(已经存在的底图颜色)以何种方式进行混合,例如文章开篇时,以源颜色和目标颜色各占0.5的方式进行混合,用式子来表示就是:xml

混合后颜色 = 源颜色 * 源因子 + 目标颜色 * 目标因子
复制代码

OpenGL内置了多种混合方式,经过glBlendFunc()来设置,第一个参数是设置源因子,第二个参数是设置目标因子,在这里,咱们须要这样设置:htm

// 设置混合方式
// Set blend functions
GLES30.glBlendFunc(GLES30.GL_SRC_ALPHA, GLES30.GL_ONE_MINUS_SRC_ALPHA)
复制代码

GL_SRC_ALPHA表示取源颜色的alpha值做为因子,GL_ONE_MINUS_SRC_ALPHA表示取1减去源颜色的alpha值做为因子,这样能获得什么效果呢?blog

先来看看源颜色的透明部分和目标颜色(底图颜色)的不透明部分混合,假设咱们的目标颜色是ARGB_DST=(1.0, a, b, c),源颜色是ARGB_SRC=(0.0, d, e, f)

此时:

混合后颜色 = ARGB_SRC * 0.0 + ARGB_DST * (1.0 - 0.0) = ARGB_DST
复制代码

再来看看源颜色的不透明部分和目标颜色(底图颜色)的不透明部分混合,假设咱们的目标颜色是ARGB_DST=(1.0, a, b, c),源颜色是ARGB_SRC=(1.0, d, e, f)

此时:

混合后颜色 = ARGB_SRC * 1.0 + ARGB_DST * (1.0 - 1.0) = ARGB_SRC
复制代码

所以效果就是,源图中的透明部分,渲染后的颜色彻底是底图颜色,等于透出了底图,源图中的不透明部分,渲染以后的颜色彻底是源图的颜色:

这样就获得了正确的效果。

咱们再来试试GL_ONE

GLES30.glBlendFunc(GLES30.GL_ONE, GLES30.GL_ONE)
复制代码

这样就是

混合后颜色 = ARGB_SRC * 1.0 + ARGB_DST * 1.0
复制代码

来看效果:

还有不少种混合方式能够设置,具体能够查询官方文档:www.khronos.org/registry/Op…

内置的混合方式有时候并不能知足咱们的要求,例如要实现:

混合后颜色 = 源颜色 * 0.123 + 目标颜色 * 0.877
复制代码

这时用内置的混合方式就不能实现,由于混合因子不能任意设置,这时能够本身在fragment shader中实现。

代码在我githubOpenGLESPro项目中,本文对应的是SampleColorBlend,项目连接:[github.com/kenneycode/…](github.com/kenneycode/…

感谢阅读!

相关文章
相关标签/搜索