OpenGL学习——混合

OpenGL中混合(Blending)通常指的是实现物体透明度(Transparency)的一种技术。在RGBA里面采用的混合模型叫“Porter-Duff”模型,通过该模型可实现混合效果。这个模型的核心公式:

结果色 = 源色 原因子 + 目标色 目标因子。
结果alpha = 源透明度 源因子 + 目标透明度 目标因子。

  • 源色即源颜色向量,这是源自纹理的颜色向量。
  • 目标色即目标颜色向量,这是当前储存在颜色缓冲中的颜色向量。
  • 源因子指定了alpha值对源颜色的影响程度。
  • 目标因子指定了alpha值对目标颜色的影响程度。

源颜色和目标颜色将会由OpenGL自动设定,但源因子和目标因子的值可以有我们来决定。这个是一个混合的默认公式,使用glBlendFunc来实现。当然的在GL中还提供一些灵活的用法。

  • 简单的Blending
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // 开启Blend
    glEnable(GL_BLEND);

    // 使用默认的Blend公式来进行混合
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    /**
    * void glBlendFunc(GLenum sfactor, GLenum dfactor);
    * 原因子和目标因子值及其含义:
    * GL_ZERO = (0, 0, 0, 0)
    * GL_ONE = (1, 1, 1, 1)
    * GL_SRC_COLOR = (sR, sG, sB, sA)
    * GL_DST_COLOR = (dR, dG, dB, dA)
    * GL_ONE_MINUS_SRC_COLOR = (1 - sR, 1 - sG, 1 - sB, 1 - sA)
    * GL_ONE_MINUS_DST_COLOR = (1 - dR, 1 - dG, 1 - dB, 1 - dA)
    * GL_SRC_ALPHA = (sA, sA, sA, sA)
    * GL_DST_ALPHA = (dA, dA, dA, dA)
    * GL_ONE_MINUS_SRC_ALPHA = (1 - sA, 1 - sA, 1 - sA, 1 - sA)
    * GL_ONE_MINUS_DST_ALPHA = (1 - dA, 1 - dA, 1 - dA, 1 - dA)
    * GL_SRC_ALPHA_SATURATE = (i, i, i, 1 )
    * /
  • 分别设置RGB和Alpha混合因子系数的Blending

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // 开启Blend
    glEnable(GL_BLEND);

    // 分别设置RGB和Alpha
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);// 这个函数和我们之前设置的那样设置了RGB分量,但这样只能让最终的alpha分量被源颜色向量的alpha值所影响到。

    /**
    * 参数是RGB或者Alpha的混合因子
    * void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
    * /
  • 指定Blend公式的Blending

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
      // 开启Blend
    glEnable(GL_BLEND);

    // 指定帧缓存区与源颜色混合的方式
    glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);

    // 允许RGB和Alpha使用不同的混合方式
    glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);

    /**
    * 可选混合公式
    * GL_FUNC_ADD:默认选项,将两个分量相加,C = S + D
    * GL_FUNC_SUBTRACT:将两个分量相减,C = S - D
    * GL_FUNC_REVERSE_SUBTRACT:将两个分量倒置并相减,C = D - S
    * GL_MIN:取分量小值,Rr=min(Rs,Rd) Gr=min(Gs,Gd) Br=min(Bs,Bd)
    * GL_MAX:取分量大值,Rr=max(Rs,Rd) Gr=max(Gs,Gd) Br=max(Bs,Bd)

Demo工程:OpenGL学习实例

图像合成滤镜

假如我们不开启GL的混合的话,默认是不处理图片的Alpha通道的才导致了下图的这种情况。这时我们有几种处理方法:

  • 假设背景是张Texture我们可以将两张Texture在着色器中使用Mix进行颜色混合。
  • 无论背景是什么,我们在着色器中判断alpha < 0.1然后进行Discard把这个片段丢弃。
  • 开启GL的混合模式。

下图是开启Blend模式的贴图: