• 一文详解 OpenGL ES 纹理颜色混合


    在OpenGL中绘制的时候,有时候想使新画的颜色和已经有的颜色按照一定的方式进行混合。例如:想使物体拥有半透明的效果,或者绘制叠加光亮的效果,这时候就需要用到OpenGLES混合
    Z轴深度由深到浅分别为:石头墙、绿色矩形、蓝色云彩
    如上图所示,为石头墙、绿色矩形、蓝色云彩 三个矩形混合后的展示效果。三个矩形(Z轴深度由深到浅)分别为,石头墙、绿色矩形、蓝色云彩。

    一、混合API

    在OpenGLES中若使用混合,需要用到API函数方法(Java):
    void glBlendFunc( int srcfactor, int destfactor );

    (1) 其OpenGL函数原型为:
    void glBlendFunc(GLenum srcfactor, GLenum destfactor);

    (2) 其功能为:
    控制新画上来的颜色 (source values, RGBA) 和 已经在帧缓冲区中的颜色 (destination values, RGBA) 的混合时源与目标 在最终颜色通道中所占的比例

    (3) 方法参数

    • srcfactor:代表源因子,即新画上来的颜色。
      该参数由九个枚举型被接受使用:
      GL_ZERO,
      GL_ONE,
      GL_DST_COLOR,
      GL_ONE_MINUS_DST_COLOR,
      GL_SRC_ALPHA,
      GL_ONE_MINUS_SRC_ALPHA,
      GL_DST_ALPHA,
      GL_ONE_MINUS_DST_ALPHA,
      GL_SRC_ALPHA_SATURATE.
    • destfactor:代表的是目标因子,即已经在帧缓冲区中的颜色。
      该参数由八个枚举型被接受使用:
      GL_ZERO,
      GL_ONE,
      GL_SRC_COLOR,
      GL_ONE_MINUS_SRC_COLOR,
      GL_SRC_ALPHA,
      GL_ONE_MINUS_SRC_ALPHA,
      GL_DST_ALPHA,
      GL_ONE_MINUS_DST_ALPHA

    二、参数含义

    • 举个栗子
    • 参数含义

    2.1 举个栗子

    我们先看一个常用混合参数搭配:

    // 最常用的混合因子搭配方式
    // 即源因子为 GL_SRC_ALPHA 目标因子为 GL_ONE_MINUS_SRC_ALPHA 
    glBlendFunc(GL30.GL_SRC_ALPHA, GL30.GL_ONE_MINUS_SRC_ALPHA);
    

    以上参数搭配方式假设:

    • (Sr, Sg, Sb, Sa)代表源颜色src(要绘制的颜色)
    • (Dr, Dg, Db, Da)代表目标颜色Dest(缓冲区中颜色)
      如果源因子的不透明度为0.2(透明度0.8),alpha值的最大值为1,那么源与目标混合后的最终颜色值为:
    // 最终颜色值为:0.2*S+0.8*D
    // OpenGL ES 最终颜色计算结果如下:
    (0.2*Sr+(1-0.2)*Dr , 0.2*Sg+(1-0.2)*Dg , 0.2*Sb+(1-0.2)*Db,0.2*Sa+(1-0.2)*Da)
    

    启用混合与纹理矩形绘制顺序代码举例:

    // 开启混合  
    gl.glEnable(GL10.GL_BLEND);  
    // 指定混合比例
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);  
      
    // 绘制石头墙纹理矩形
    gl.glPushMatrix();  
    gl.glTranslatef(-0.8f, -0.8f, -0.02f);  
    wallRect.drawSelf(gl, tex_wall);  
    gl.glPopMatrix();  
      
    // 绘制绿色纹理矩形
    gl.glPushMatrix();  
    gl.glTranslatef(0, 0, -0.01f);  
    greenRect.drawSelf(gl, tex_green);  
    gl.glPopMatrix();  
      
    // 绘制蓝色云彩纹理矩形
    gl.glPushMatrix();  
    gl.glTranslatef(0.8f, 0.8f, 0f);  
    cloudRect.drawSelf(gl, tex_cloud);  
    gl.glPopMatrix();`
    
    

    2.2 参数含义

    有了上边的例子,我们再回来看各个参数因子。

    假设:

    • (Sr, Sg, Sb, Sa)代表源颜色src(要绘制的颜色)
    • (Dr, Dg, Db, Da)代表目标颜色Dest(缓冲区中颜色)
    • (Kr, Kg, Kb, Ka)代表缓冲区中各个通道R, G, B, A的最大值。

    那么各个参数因子所代表的值如下表所示:

    混合因子 各颜色通道色彩比例值
    GL_ZERO (0,0,0,0)
    GL_ONE (1,1,1,1)
    GL_SRC_COLOR (Sr/Kr, Sg/Kg, Sb/Kb, Sa/Ka)
    GL_DST_COLOR (Dr/Kr, Dg/Kg, Db/Kb, Da/Ka)
    GL_ONE_MINUS_SRC_COLOR (1,1,1,1) - (Sr/Kr,Sg/Kg,Sb/Kb,Sa/Ka)
    GL_ONE_MINUS_DST_COLOR (1,1,1,1) - (Dr/Kr,Dg/Kg,Db/Kb,Da/Ka)
    GL_SRC_ALPHA ( Sa/Ka, Sa/Ka, Sa/Ka, Sa/Ka )
    GL_ONE_MINUS_SRC_ALPHA (1,1,1,1) - (Sa/Ka,Sa/Ka,Sa/Ka,Sa/Ka)
    GL_DST_ALPHA ( Da/Ka, Da/Ka, Da/Ka, Da/Ka )
    GL_ONE_MINUS_DST_ALPHA (1,1,1,1) - (Da/Ka,Da/Ka,Da/Ka,Da/Ka)
    GL_SRC_ALPHA_SATURATE (min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,min(Sa, Ka, Da)/Ka,1)

    三、 几种常用混合方式效果

    下边以三张纹理图片在不同混合因子设置下的效果图,对几种常见的混合效果进行举例说明。

    • 其中 离摄像机最远的为一张 Alpha=1.0石头墙纹理图;
    • 其次 为一张 Alpha=0.6蓝色云彩纹理图;
    • 最后离摄像机最近的为一张 Alpha=0.4的绿色纹理图。

    3.1 混合(GL_ONE, GL_ZERO)

    源颜色(最后绘制的绿色矩形)参数因子为GL_ONE,目标色(缓冲区中颜色)参数因子为GL_ZERO。

    这种参数因子组合混合比例 (1.0, 0.0)

    • 源颜色(最后绘制的绿色矩形)覆盖目标色(缓冲区中颜色);
    • 目标色(缓冲区中颜色)不起作用,

    其运行效果如下图所示:
    混合方式(GL_ONE, GL_ZERO)

    3.2 混合(GL_ONE, GL_ONE)

    源颜色(最后绘制的绿色矩形)与 目标色(缓冲区中颜色)均为GL_ONE。

    这种参数因子组合混合比例 (1.0, 1.0)

    • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色)在混合时,源与目标的色彩通道颜色所占的比例相同

    其运行效果如下图所示:
    混合方式(GL_ONE, GL_ONE)

    仔细观察以上效果图,可以看到三张图片叠加部分,几乎为白色。

    3.3 混合(GL_ONE, GL_ONE_MINUS_DST_ALPHA)

    源颜色(最后绘制的绿色矩形)参数因子为 GL_ONE,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_DST_ALPHA。

    这种参数因子组合混合比例 (1.0, 1.0-Da/Ka)

    • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色),在混合时取源颜色 (1- Da/Ka)比例进行混合。

    其运行效果如下图所示:
    混合方式(GL_ONE, GL_ONE_MINUS_DST_ALPHA)

    观察以上效果图:可以看到最上边绿色矩形占最终混合颜色的比例较高。
    三张纹理绘制时:

    • 前两张纹理混合时:源颜色为蓝色云彩纹理矩形,目标颜色为石头墙纹理矩形
      由于混合比例为 (1.0, 1.0-Da/Ka),混合后的最终颜色只显示蓝色云彩纹理矩形(石头墙纹理的ALPHA=1.0,最终石头墙颜色所占的比例 1.0-1.0=0.0,比例为0)。
    • 其次绿色纹理矩形缓冲区中颜色进行混合:源颜色为绿色纹理矩形,目标颜色为缓冲区中颜色
      混合后的最终颜色基本只显示绿色纹理矩形(蓝色云彩纹理矩形的ALPHA=0.6,(1-0.6)云纹理与绿色矩形混合后,几乎看不到云纹理的颜色)。

    3.4 混合 (GL_SRC_ALPHA, GL_ONE)

    源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE。

    这种参数因子组合混合比例 (Sa/Ka, 1.0)

    • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色),在混合时以源颜色值乘以Sa/Ka与目标颜色值相加。

    其运行效果如下图所示:
    混合方式 (GL_SRC_ALPHA, GL_ONE)

    观察以上效果图,可以看出目标墙面与云纹理混合后墙面纹理颜色值所占比例较高,三个纹理图片叠加部分有些像素点为白色。

    3.5 混合 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    这种方式是最常用的混合方式,源颜色(最后绘制的绿色矩形)参数因子为 GL_SRC_ALPHA,目标色(缓冲区中颜色)参数因子为 GL_ONE_MINUS_SRC_ALPHA。

    这种参数因子组合混合比例 (Sa/Ka, 1.0-Sa/Ka)

    • 源颜色(最后绘制的绿色矩形)目标色(缓冲区中颜色)在混合时,取源颜色的 (Sa/Ka) 与目标颜色 (1.0-Sa/Ka) 相加计算最终的颜色值。

    其运行效果如下图所示:
    混合方式 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    附案例代码

    案例源码下载地址:
    https://download.csdn.net/download/aiwusheng/64038379

    = THE END =

    欢迎关注我的公众号

  • 相关阅读:
    QEMU KVM Libvirt手册(10):Managing Virtual Machines with libvirt
    Openssl的证书操作
    QEMU KVM Libvirt手册(10): KVM的各种限制
    QEMU KVM Libvirt手册(9): network
    nginx调优(一)
    Apache调优(二)
    Apache调优(一)
    使用Varnish为网站加速
    Linux系统调优——系统整体运行状态排查(六)
    Linux系统调优——内核相关参数(五)
  • 原文地址:https://www.cnblogs.com/xiaxveliang/p/15694599.html
Copyright © 2020-2023  润新知