混合

作者: 不决书 | 来源:发表于2023-09-16 08:43 被阅读0次

    混合(Blending)通常是实现物体透明度(Transparency)的一种技术。


    image.png

    丢弃片段

    #version 330 core
    out vec4 FragColor;
    
    in vec2 TexCoords;
    
    uniform sampler2D texture1;
    
    void main()
    {             
        vec4 texColor = texture(texture1, TexCoords);
        if(texColor.a < 0.1)
            discard;
        FragColor = texColor;
    }
    

    注意,当采样纹理的边缘的时候,OpenGL会对边缘的值和纹理下一个重复的值进行插值(因为我们将它的环绕方式设置为了GL_REPEAT。这通常是没问题的,但是由于我们使用了透明值,纹理图像的顶部将会与底部边缘的纯色值进行插值。这样的结果是一个半透明的有色边框,你可能会看见它环绕着你的纹理四边形。要想避免这个,每当你alpha纹理的时候,请将纹理的环绕方式设置为GL_CLAMP_TO_EDGE:
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    混合

    要想渲染有多个透明度级别的图像,我们需要启用混合(Blending)。

      glEnable(GL_BLEND);
    

    OpenGL中的混合是通过下面这个方程来实现的:


    image.png

    有一个专门的函数,叫做glBlendFunc
    glBlendFunc(GLenum sfactor, GLenum dfactor)函数接受两个参数,来设置源和目标因子。OpenGL为我们定义了很多个选项,我们将在下面列出大部分最常用的选项。注意常数颜色向量C¯constant
    可以通过glBlendColor函数来另外设置。

    image.png

    为了获得之前两个方形的混合结果,我们需要使用源颜色向量的alpha
    作为源因子,使用1−alpha
    作为目标因子。这将会产生以下的glBlendFunc:

      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    

    也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项:

      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
    

    glBlendEquation(GLenum mode)允许我们设置运算符,它提供了三个选项:

    • GL_FUNC_ADD:默认选项,将两个分量相加:C¯result=Src+Dst

    • GL_FUNC_SUBTRACT:将两个分量相减: C¯result=Src−Dst

    • GL_FUNC_REVERSE_SUBTRACT:将两个分量相减,但顺序相反:C¯result=Dst−Src

      深度测试和混合一起使用的话会产生一些麻烦。当写入深度缓冲时,深度缓冲不会检查片段是否是透明的,所以透明的部分会和其它值一样写入到深度缓冲中。结果就是窗户的整个四边形不论透明度都会进行深度测试。即使透明的部分应该显示背后的窗户,深度测试仍然丢弃了它们。
      所以我们不能随意地决定如何渲染窗户,让深度缓冲解决所有的问题了。这也是混合变得有些麻烦的部分。要想保证窗户中能够显示它们背后的窗户,我们需要首先绘制背后的这部分窗户。这也就是说在绘制的时候,我们必须先手动将窗户按照最远到最近来排序,再按照顺序渲染。

    相关文章

      网友评论

          本文标题:混合

          本文链接:https://www.haomeiwen.com/subject/qbibvdtx.html