OpenGLES demo - 7. Alpha Blend

来源:互联网 发布:知乎 软件下载安卓 编辑:程序博客网 时间:2024/06/06 11:05

原创文章,转载请注明链接 http://blog.csdn.net/hoytgm/article/details/36928677

这次我们研究研究一个很重要的功能,Alpha Blend,也就是Alpha混色。这个功能在游戏和程序中是非常非常的常见,透明的效果就是靠它实现的!如果没有这个功能,难以想象显示效果会有多渣。。。


那什么是OpenGLES中的Alpha Blend呢?简单的说,就是两个或两个以上的层次结构(有可能是物体与物体之间,也有可能是物体与背景色之间)相交的部分,呈现出另外一种颜色,也就是这些物体组合起来的颜色。在OpenGLES中,也是图形渲染中,做Alpha Blend有两个先决条件:1,需要透明的物体要处于参照物体的前面,这样才能过深度测试;2,透明的物体一定要最后画。对于第一点,还需要补充一下,透明物体位于参照物体的前面,是当深度测试为LESS或LEQUAL或ALWAYS的时候,如果深度测试是GREAT,那么透明物体就要位于参照物体的后面才能通过深度测试,不过这时候可能看起来效果会怪怪的,大家不妨试试。。。


知道了Alpha Blend的大概描述,那我们继续讲讲Alpha Blend的混色方式吧。混色需要两个颜色才能完成,我们称他们为混色的源(Src)和目标(Dst),最终的结果我们叫做R。这里可以提一下,如果我们只画一个三角形,那么这个三角形就是源,而背景色就是目标。一个非常明显并且十分简单的公式就是

<p>R = SRC + DST</p>


混色还需要一个叫做混色因子(F)的东西,来决定SRC和DST要取多少来参加混色。并且SRC和DST的F是可能不同的,那么我们就有了Fsrc和Fdst,那么我们这个公式就变成了

R = SRC * Fsrc + DST * Fdst

混色因子的选择有很多种,对于SRC的话,我们可以用SRC的颜色作为混色因子,即Fsrccolor,我们也可以用SRC的Alpha通道来作为混色因子,即Fsrcalpha。对于DST,也是同样的道理。不仅如此,OpenGLES还提供了很多的混色因子,比如GL_ZERO, GL_ONE,这两个分别是0和1。如果我们把GL_ZERO作为SRC的混色因子,而GL_ONE作为DST的混色因子,那么带入上面的公式,R = SRC * 0 + DST * 1 = DST,这样的话,相当于三角形没有画上去。

混色因子还有GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,他们分别代表了混色因子为源颜色值,1-源颜色值,源Alpha值,1-源Alpha值,目标Alpha值,1-目标Alpha值,目标颜色值,1-目标颜色值。

当我们选用这些混色因子的时候,再带入上面的公式,就可以算出最后的结果是什么了。


当然,混色还有一个混色公式,在我们上面写的两个公式中,我们的混色公式都采用了相加的方式,我们也可以用相减的方式来做
R = SRC * Fsrc - DST * Fdst
所以,混色公式就有了GL_FUNC_ADD和GL_FUNC_SUBTRACT


好了,理论的东西我们讲到这里,开始加代码吧。首先两个先决条件,我们用两个Draw命令画两个三角形,第一个三角形的深度值为0.5,第二个三角形的深度值为0.0,并且深度比较公式为GL_LESS。我们这里把Fragment Shader稍微改动了一下,用于画两种颜色,具体可以看资源里面的源码。

    glEnable(GL_DEPTH_TEST);    glDepthFunc(GL_LESS);        float firsttriangle[] =    {        -0.8f, -0.8f, 0.5f, 1.0f,        0.8f, -0.8f, 0.5f, 1.0f,        0.0f, 0.5f, 0.5f, 1.0f,    };    float secondtriangle[] =    {        -0.8f, 0.8f, 0.0f, 1.0f,        0.8f, 0.8f, 0.0f, 1.0f,        0.0f, -0.5f, 0.0f, 1.0f,    };        glUniform1i(uLocFirst, 1);    glVertexAttribPointer(aLocPos, 4, GL_FLOAT, 0, 0, firsttriangle);    glDrawArrays(GL_TRIANGLES, 0, 3);        glUniform1i(uLocFirst, 0);    glVertexAttribPointer(aLocPos, 4, GL_FLOAT, 0, 0, secondtriangle);    glDrawArrays(GL_TRIANGLES, 0, 3);

我们画出来的结果是这样的,第二个红色的三角形覆盖了第一个绿色的三角形


然后我们首先开始启用Alpha Blend

glEnable(GL_BLEND);

接着我们设置混色因子,将源混色因子设置为源颜色值,目标混色因子设置为1-源颜色值,这也是透明效果的一个比较常用的选择。同时,我们将混色公式设置为相加

    glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR);    glBlendEquation(GL_FUNC_ADD);
我们先把这个公式和混色因子带入上面的公式,看下应该得到什么效果?

先看源颜色的Red, Green, Blue和Alpha为 (1, 0, 0, 1), 目标颜色为 (0, 1, 0, 1),所以源颜色四个分量的混色因子为 (1, 0, 0, 1), 而目标颜色四个分量的混色因子为1-(1, 0, 0, 1) 为(0, 1, 1, 0),这个结论很好得到吧?那么我们开始计算最终颜色的红色分量为 Rred = SRCred * Fsrc_red + DSTred * Fsrc_red = 1 * 1 + 0 * 1 = 1,同理,Rgreen = 0 * 0 + 1 * 1 = 1, Rblue = 0 * 0 + 0 * 1 = 0, Ralpha = 1 * 1 + 1 * 0 = 1, 所以,最终结果为 (1, 1, 0, 1),应该是一个黄色。


我们再画一次,看下效果



看!没错吧,两个三角形重叠的部分变成了黄色!


大家改改混色公式为减法,然后带入公式计算一下,再看看效果?

代码已经上传了,地址为http://download.csdn.net/detail/hoytgm/7596243,欢迎大家下载。


参考:http://blog.csdn.net/sjzcandy/article/details/5775633

0 0
原创粉丝点击