开启深度测试后,如果重叠的图层中,上层的图层是半透明的情况下我们不能采用直接覆盖的方式,而需要用到混合,在图层重叠的部分绘制的是混合后的内容。

首先我们绘制两个矩形,上层橙色矩形为半透明,下层绿色矩形为不透明,在不打开颜色混合时效果如下:
void renderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
GLfloat vOrange[] = {255 / 255.0, 127 / 255.0, 80/ 255.0, 0.75f};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
greenBatch.Draw();
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vOrange);
orangeBatch.Draw();
glutSwapBuffers();
glDisable(GL_DEPTH_TEST);
}

可以发现在为打开混合的情况下,重叠部分并没有出现我们预期的现象。接下来我们打开颜色混合代码。
void renderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
// 打开颜色混合
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
GLfloat vOrange[] = {255 / 255.0, 127 / 255.0, 80/ 255.0, 0.75f};
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
greenBatch.Draw();
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vOrange);
orangeBatch.Draw();
glutSwapBuffers();
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
}

打开&关闭 (单纯的将两个图层重叠时)
//开启,
glEnable(GL_BlEND);
//关闭
glDisable(GL_BlEND);
开关方式 + 混合方程式 ()
//开启,
glEnable(GL_BlEND);
//设置混合因子--默认值是 GL_SRC_ALPHA 和 GL_ONE_MINUS_SRC_ALPHA
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
//关闭
glDisable(GL_BlEND);
-
glBlendFunc
中的参数不同,则混合计算公式就不同 - 默认为传参为
GL_SRC_ALPHA
和GL_ONE_MINUS_SRC_ALPHA
, 其对应的计算公式为:
//Cf -- 最终组合的颜色值
//Cd:源颜色 -- 当前渲染命令传入的颜色值
//CS:目标颜色 -- 颜色缓冲区中已经存在的颜色值
//S:源混合因子
//D:目标混合因子
Cf = (Cs * S) + (Cd * D)
网友评论