OpenGL颜色混合

1,035 阅读3分钟

颜色混合

OpenGL渲染时会把颜色值存在颜色缓冲区中,每个像素点的深度值存在深度缓冲区。

当两个图层中至少有一个的透明度不等于1,即半透明状态时,两个图层重叠在一起的部分,就不可以简单的,根据深度测试的结果,来对颜色缓冲区的的值进行覆盖,而是需要将两个颜色进行混合后,存入颜色缓冲区。

上图中红色z值要大于绿色,仅以深度测试的话重叠部分应该是红色,但又因为红色是半透明状态,所以重叠部分的颜色值需要进行计算后才能存储到颜色缓冲区。

//开启颜色混合
glEnable(GL_BlEND);
//关闭颜色混合
glDisable(GL_BLEND);

名词解释

  • 目标颜色:已经存储在颜色缓冲区中的颜色值
  • 源颜色:作为当前渲染命令结果进入颜色缓冲区中的颜色值

这里不要被名字所误解,可以理解为目标颜色在前,源颜色在后,开启颜色混合开关后,两个颜色通过默认的混合方程式计算:

 Cf = (Cs * s) + (Cd * D);
 Cf:指颜色混合计算的最终结果
 Cs:源颜色
 Cd:目标颜色
 S:源混合因子
 D:目标混合因子

当然,在固定着色器/可编程着色器中对两个图层进行渲染,可以使用开启颜色混合开关的方式,OpenGL会通过默认的混合方程式进行颜色的混合计算&渲染。

但是在某些实际情况下,我们需要给一张图片加颜色滤镜时,就不可以直接交给默认的混合方程式来计算结果,因为就没有两个图层,滤镜的颜色需要我们自己手动添加。

可编程着色器 -> 片元着色器 -> 处理图片原图颜色+滤镜颜色 -> 套用颜色混合方程式

自定混合

设置混合因子

设置混合因子,需要使用glBlendFun函数

glBlendFun(GLenum S, GLenum D);
S:源混合因子
D:目标混合因子

  • 表中R、G、B、A 分别代表 红、绿、蓝、alpha。
  • 下标S、D,分别代表源、⽬标
  • C 代表常量颜⾊(默认⿊⾊)

常用的混合函数组合

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

混合计算举例

Cd = (1.0f,0.0f,0.0f,1.0f); //目标颜色
Cs = (0.0f,0.0f,1.0f,0.6f); //源颜色
// 源混合因子S设置为‘GL_SRC_ALPHA’,对应表中As=源颜色透明度值
S = 0.6f;
// 目标混合因子D设置为‘GL_ONE_MINUS_SRC_ALPHA’,对应表中1-As=1-源颜色透明度值
D = 0.4f;

Cf = (Cs * 0.6f) + (Cd * 0.4f)

混合函数经常用于实现在其他一些不透明的物体前⾯绘制⼀个透明物体的效果。

修改混合方程式

//选择混合方程式的函数
glbBlendEquation(GLenum mode)

mode模式有

//修改常量混合颜色C的函数,默认为黑色
glBlendColor(GLclampf red, GLclampf gree, GLclampf blue, GLclampf alpha)

使用

    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
    // 开启颜色混色
    glEnable(GL_BLEND);
    // 开启组合函数
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    // 渲染可移动的图形
    squareBatch.Draw();
    // 关闭颜色混合
    glDisable(GL_BLEND);