陈江川

邮箱:jiangchuanc@gmail.com

OpenGL ES 05-混合片元颜色

当纹理计算出来一个完全不透明的最终片元颜色时,这个片元颜色会简单地替换任何在帧缓存的像素颜色渲染缓存内现存的对应的像素颜色(这句话有点拗口,多看几遍)。

如果计算出来的片元颜色部分透明或者全透明,OpenGL ES会使用一个混合函数来混合片元颜色与像素颜色渲染缓存内对应的像素。

三角形内的纹理与在帧缓存的黑色像素混合,三角形内的纹理是完全不透明,所以替换掉帧缓存中像素颜色渲染缓存内的黑色像素。

  • 第二段的内容是这篇要讲解的,现在有两个纹理混合在一起,那么最终每个片元的颜色怎么计算出来的?下面是混合纹理的不同算法的结果:

上面有说到,如果计算出来的片元颜色部分透明或者全透明,OpenGL ES会使用一个混合函数来混合片元颜色与像素颜色渲染缓存内对应的像素。现在就来了解下这个函数:

/*
    第一个参数:源因子
    第二个参数:目标因子
 */
GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);

这个混合函数的计算公式是这样的:

假设:
源颜色的四个分量红/绿/蓝/透明度为:(sR, sG, sB, sA);
源因子为:(sfR, sfG, sfB, sfA);
目标颜色四分量:(dR, dG, dB, dA);
目标因子为:(dfR, dfG, dfB, dfA).

那么混合后的新颜色为:

(sR * sfR + dR * dfR, sG * sfG + dG * dfG, sB * sfB + dB * dfB, sA * sfA + dA * dfA)

glBlendFunc函数的第一个参数决定了源因子的值;第二个参数决定了目标因子的值。

现在看看参数值:

GL_ZERO:表示使用0.0作为因子,实际上相当于不使用该颜色参与混合运算;
GL_ONE:表示使用1.0作为因子,实际上相当于完全使用该颜色参与混合运算;
GL_SRC_ALPHA:表示使用源颜色的alpha值作为因子;
GL_DST_ALPHA:表示使用目标颜色的alpha值作为因子;
GL_ONE_MINUS_SRC_ALPHA:表示用(1.0 - 源颜色的alpha)来作为因子;
GL_ONE_MINUS_DST_ALPHA:表示用(1.0 - 目标颜色的alpha)来作为因子;
GL_SRC_COLOR:源颜色的四个分量分别作为因子的四个分量
......

Demo中我们使用的是:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

计算结果(依旧使用上面的假设):
混合后的Red分量:sR * sfR + dR * (1.0 - sfR)
混合后的Green分量:sG * sfG + dG * (1.0 - sfR)
混合后的Blue分量:dB * dfB, sA * (1.0 - sfR)
混合后的Alpha分量:sA * sfA + dA * (1.0 - sfR)

« OpenGL ES 06-多重纹理 直播/视频监控那点事 »