OpenGL 渲染技巧:混合

986 阅读3分钟
  • 混合概念(gl_blend)

    • 没开启混合之前两个颜色片段重合处理方法
      首先颜色值会放在颜色缓冲区中,然后每个片段的深度值会放在深度缓冲区中,当没有开启深度测试的时候,那么后渲染的颜色会覆盖当前片段中存储的颜色,但是当开启了深度测试则会比较两个片段的深度值跟接近临近的裁剪平面才会替换原来的颜色片段
    • 开启混合之后两个颜色片段重合处理方法
      将源色和目标色以某种方式混合生成特效的技术。混合常用来绘制透明或半透明的物体。在混合中起关键作用的α值实际上是将源色和目标色按给定比率进行混合,以达到不同程度的透明。α值为0则完全透明,α值为1则完全不透明。混合操作只能在RGBA模式下进行,颜色索引模式下无法指定α值。物体的绘制顺序会影响到OpenGL的混合处理(会将混合后的颜色值替换目标颜色)
    • 混合开启、关闭方法
      • 开启:glEnable(GL_BLEND)
      • 关闭:glDisable(GL_BLEND)
  • 组合颜色

    • 目标颜色: 已经存在颜色缓冲区中的值(切记根据字面意思理解)
    • 源颜色: 作为当前渲染命令结果进入颜色缓冲区的颜色值也就是将要存储的颜色值(同样的切记根据字面意思理解)
    • 组合方式: 组合方式是按照混合方程式控制的,在默认的情况下组合方程式是:
      Cf=(Cs * S)+(Cd * D)
      Cf: 最终计算得出的颜色
      Cs: 源颜色
      Cd:目标颜色
      S: 源混合因子
      D: 目标混合因子
    • 修改默认混合方程式
      默认的混合方程式是:Cf=(Cs * S)+(Cd * D) 可通过glbBlendEquation(GLenum mode);方法进行修改具体参数如下:
      模式 函数
      GL_FUNC_ADD Cf=(Cs * S)+(Cd * D)
      GL_FUNC_SUBTRACT Cf=(Cs * S)-(Cd * D)
      GL_FUNC_REVERSE_SUBTRACT Cf=(Cd * D)-(Cs * S)
      GL_MIN Cf=min(Cs,Cd)
      GL_MAX Cf=max(Cs,Cd)
  • 混合因子

    • 设置混合因子
      glBlendFunc(GLenum S, GLenum D);
      S:源混合因子
      D:目标混合因子

    • OpenGL混合因子对照表

      函数 RGB混合因子 Alpha混合因子
      GL_ZERO (0,0,0) 0
      GL_ONE (1,1,1) 1
      GL_SRC_COLOR (Rs,Gs,Bs) As
      GL_ONE_MINUS_SRC_COLOR (1,1,1)-(Rs,Gs,Bs) 1-As
      GL_DST_COLOR (Rd,Gd,Bd) Ad
      GL_ONE_MINUS_DST_COLOR (1,1,1)-(Rd,Gd,Bd) 1-Ad
      GL_SRC_ALPHA (As,As,As) As
      GL_ONE_MINUS_SRC_ALPHA (1,1,1)-(As,As,As) 1-As
      GL_DST_ALPHA (Ad,Ad,Ad) Ad
      GL_ONE_MINUS_DST_ALPHA (1,1,1)-(Ad,Ad,Ad) 1-Ad
      GL_CONSTANT_COLOR (Rc,Gc,Bc) Ac
      GL_ONE_MINUS_CONSTANT_COLOR (1,1,1)-(Rc,Gc,Bc) 1-Ac
      GL_CONSTANT_ALPHA (Ac,Ac,Ac) Ac
      GL_ONE_MINUS_CONSTANT_ALPHA (1,1,1)-(Ac,Ac,Ac) 1-Ac
      GL_SRC_ALPHA_SATURATE (f,f,f)*f=min(As,1-Ad) 1

      注:表中R、G、B、A分别代表红、绿、蓝、alpha。S、D,分别代表源、目标颜色。C代表常量颜色(默认黑色)

  • 案列分析

    首先确定混合公式是glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    如果颜⾊缓存区已经有⼀种颜⾊红⾊(1.0f,0.0f,0.0f,0.0f),这个⽬标颜⾊Cd,如果在这上⾯⽤⼀ 种alpha为0.6的蓝⾊(0.0f,0.0f,1.0f,0.6f)
    Cd (⽬标颜⾊) = (1.0f,0.0f,0.0f,0.0f);
    Cs (源颜⾊) = (0.0f,0.0f,1.0f,0.6f);
    S = 源alpha值 = 0.6f
    D = 1 - 源alpha值= 1-0.6f = 0.4f
    ⽅程式Cf = (Cs * S) + (Cd * D)
    等价于 = (Blue * 0.6f) + (Red * 0.4f)
    结论: 最终颜⾊是以原先的红⾊(⽬标颜⾊)与 后来的蓝⾊(源颜⾊)进⾏组合。源颜⾊的alpha值 越⾼,添加的蓝⾊颜⾊成分越⾼,⽬标颜⾊所保留的成分就会越少。 混合函数经常⽤于实现在其他⼀些不透明的物体前⾯绘制⼀个透明物体的效果

  • 常量混合颜色

    常量混合颜⾊,默认初始化为⿊⾊(0.0f,0.0f,0.0f,0.0f),但是还是可以修改这个常量混合颜⾊。
    void glBlendColor(GLclampf red ,GLclampf green ,GLclampf blue ,GLclampf alpha );