美文网首页
OpenGL中图层混合公式的一点探讨

OpenGL中图层混合公式的一点探讨

作者: 默默_David | 来源:发表于2020-07-15 14:51 被阅读0次

OpenGL中图层混合公式的一点探讨

一、问题的提出

OpenGL混合的时候,常常会用到如下一个公式:

Cf = (Cs * S) + (Cd * D)

其中
Cf表示最终计算得出的颜色
Cs表示源颜色(作为当前渲染命令结果进⼊入颜⾊缓存区的颜色值)
Cd表示目标颜色(已经存储在颜⾊缓存区的颜⾊值)
S表示源混合因子
D表示目标混合因子

我们设置一个demo来看,其中渲染五个矩形,居中可以移动的大红色矩形先绘制,作为目标颜色,我们分别查看渲染后的结果,主要代码如下:

void RenderScene(void)
{
    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
   
    //1.开启混合
    glEnable(GL_BLEND);
    //2.开启组合函数 计算混合颜色因子
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    //定义4种颜色
    //全红色先进行绘制,作为目标颜色
    GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
    GLfloat vRed1[] = { 1.0f, 0.0f, 0.0f, 0.5f };
    GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 0.5f };
    GLfloat vBlue[] = { 0.0f, 0.0f, 1.0f, 0.5f };
    GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 0.5f };
    
    
    //绘制大红色矩形,作为目标颜色
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    squareBatch.Draw();
    
    //绘制四个源颜色矩形
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
    greenBatch.Draw();
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed1);
    redBatch.Draw();
    
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vBlue);
    blueBatch.Draw();
    

    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vBlack);
    blackBatch.Draw();
    
    //5.关闭混合功能
    glDisable(GL_BLEND);
    
    //同步绘制命令
    glutSwapBuffers();
}
//上下左右键位控制大红色矩形移动
void SpecialKeys(int key, int x, int y)
{
    ...
    上下左右移动作为目标颜色矩形的代码
    ...
    //移动后触发重绘
    glutPostRedisplay();
}

直接运行后,初始效果如下:

初始效果

然后我们移动中央矩形,分别和其它四个重合,显示的结果如下:


重合绿色
重合紫色
重合灰色
重合粉色

如图所示,在和绿色、紫色、灰色重合时,看上去没有任何问题

但是在和粉色重合时,我们发现,重合部分直接是红色,没有任何的变化。

按照我们的公式Cf = (Cs * S) + (Cd * D),Cs为{1,0,0,0.5},S为0.5,Cd为{1,0,0,1},D为0.5,按照我们向量计算公式,Cf应该为{1,0,0,0.75},这和我们的结果完全不一致。这到底是什么原因呢?

改变颜色值来测试并得出结果

我们分别设置Cs为{1,0,0,0.5},Cd为{1,0,0,0.8}来测试结果:

结果

我们可以发现,重合区域明显比{1,0,0,0.8}要深,按照公式计算得出结果应该是{1,0,0,0.65},结果明显比计算出的结果要深。

我们再设置Cs为{1,0,0,0.2},Cd为{1,0,0,0.1}来测试结果:

结果
可以看到,结果也是比计算结果{1,0,0,0.1}要深。

根据以上结果,我们发现直接套用公式和实际显示的结果是不一致的

那么,我们换一个思路,一个{r,g,b,a}的颜色,我们可以改变写法为{r*a,g*a,b*a,1},那么我们对上述三个案例的颜色值与最终结果进行比较,可以发现最终颜色应该为:

Cf = (Cs的RGB值 * S) + ((Cd的RGB值 * Cd的alpha值)*D)

对于上述三个案例,分别可以得出:

  1. Cs为{1,0,0,0.5},S为0.5,Cd为{1,0,0,1},D为0.5,结果为{1,0,0,1}
  2. Cs为{1,0,0,0.5},S为0.5,Cd为{1,0,0,0.8},D为0.5,结果为{0.9,0,0,1}
  3. Cs为{1,0,0,0.2},S为0.2,Cd为{1,0,0,0.1},D为0.8,结果为{0.28,0,0,1}

对于以上三个结果,我们也可以转换为带透明度的值,分别为

  1. Cf为{1,0,0,1},Cs为{1,0,0,0.5},Cd为{1,0,0,1}
  2. Cf为{1,0,0,0.9},Cs为{1,0,0,0.5},Cd为{1,0,0,0.8}
  3. Cf为{1,0,0,0.28},Cs为{1,0,0,0.2},Cd为{1,0,0,0.1}

将它们分别和我们案例中的结果进行对比,发现和我们案例中的结果完全符合

所以,我们实际用于计算的的混合方程式应该为:

Cf(alpha为1) = (Cs的RGB值 * S) + ((Cd的RGB值 * Cd的alpha值)*D)

上述仅仅个人研究的一点心得,如果有不对的地方欢迎各位朋友留言探讨

相关文章

  • OpenGL中图层混合公式的一点探讨

    OpenGL中图层混合公式的一点探讨 一、问题的提出 OpenGL混合的时候,常常会用到如下一个公式: 其中Cf表...

  • 图层混合模式公式

    公式贴图: 注释: 1.混合模式的数学计算公式,另外还介绍了不透明度。 2.这些公式仅适用于RGB图像,对于Lab...

  • 色彩篇06 | Photoshop中有关图层混合模式中的“正片叠

    Photoshop中有关图层混合模式中的“正片叠底”计算公式 1.查看每个通道中的颜色信息,并将基色与混合色复合。...

  • 混合模式

    混合模式,简单来说就是在图层基础上进行某种公式运算,使多个图层以不同效果混合起来。 每一种混合模式都是一种运算,运...

  • PS中27种图层混合模式原理详解

    基本概念 进行图层混合时,上图层为混合色,下图层为基色,混合产生的最终效果为结果色。 “基色”:“基色”是图像中的...

  • PS第三篇——文字火焰特效

    一、重点:图层的混合选项和混合特效 右击文字缩略图,点击混合选项 混和选项中的混合模式在右侧图层窗口上方也有 二、...

  • Java图像处理之正片叠底

    正片叠底,在Photoshop中是一种混合模式,简单的说就是可以让2个图层的内容融合起来。 融合的计算公式其实非常...

  • 图层混合

    图层混合

  • PS中27种图层模式入门

    1.正常模式(Normal) 默认模式,显示混合色图层的像素,没有进行任何的图层混合。这意味着基色图层(背景图层)...

  • 图层混合模式 _By Serene

    选图: 高于50%灰: 低于50%灰: 图层混合模式# 正常## 不与其他图层发生任何混合。使用时用当前图层的颜色...

网友评论

      本文标题:OpenGL中图层混合公式的一点探讨

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