8.OpenGL学习之颜色混合

颜色混合

  通常情况下OpenGL渲染时会把颜色值放在颜色缓冲区中。每个片段的深度值也是放在深度缓冲区中的。当深度测试被关闭(禁用)时,新的颜色值简单得覆盖颜色缓冲区中已经存在的其他值。当深度测试被打开(启用)时,新的颜色片段只有当它们比原来的值更接近邻近的裁剪平面时才会替换原来的颜色片段。在正常情况下,任何绘制不是被完全丢弃,就是完全覆盖原来的颜色值,这取决于深度测试的结果。如果打开了OpenGL的混合功能,那么下层的颜色值就不会被清除。

glEnable(GL_BLEND);

在打开混合功能的情况下,新的颜色会与已经存在的颜色值在颜色缓冲区进行组合。这些颜色的组合方式不同会导致很多不同的特殊效果。

组合颜色

  假设绘制这样一个场景:透过红色的玻璃看绿色的物体。那么可以先绘制绿色的物体,再绘制红色的玻璃。在绘制红色的玻璃时,利用颜色混合得到一种新的颜色,使玻璃看起是半透明的。
已经存储在颜色缓冲区中的颜色值叫做目标颜色,即上面的绿色。作为当前渲染命令的结果进入颜色缓冲区的颜色值称为源颜色,即上面玻璃的红色。
当混合功能被开启时,源颜色和目标颜色的组合方式是由混合方程式控制的。默认情况下,混合方程式如下所示。
这里写图片描述
其中,Cf是最终计算产生的颜色,Cs是源颜色,Cd则是目标颜色,S和D分别是源和目标混合因子。这写混合因子是用下面函数进行设置。

void glBlendFunc (GLenum S, GLenum D);

S和D都是枚举值,而不是可以直接指定的实际值。 下图列出了混合函数可以使用的值。其中下标表示源、目标和颜色。R、G、B和A分别代表红、绿、蓝和alpha。
这里写图片描述
我们通过一个常见的混合颜色组合来举例说名。

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

这个函数告诉OpenGL接受源源颜色并将这个颜色(RGB值)与alpha值相乘,然后把这个结果加上目标颜色乘以“1减去源颜色的alpha值”的结果。
这个混合函数经常用于实现在其他一些不透明的物体前面绘制一个透明物体的效果。但是,这种技巧需要首先绘制一个或多个背景物体,然后再在上面绘制经过混合的透明物体。

改变混方程式

上面提及的混合方程式是默认的。实际上我们可以从五种不同的混合方程式进行选择,如下图所示,我们可以通过下面函数进行选择。

 void glBlendEquation(GLenum mode);    

这里写图片描述

示例演示

设置颜色混合。将颜色RGB(1.0,1.0,0.0)和50%透明效果的纹理绘制立方体。

void MyQGLWidget::initializeGL()
{
    loadGLTextures();
    glEnable(GL_TEXTURE_2D);
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //设置清除屏幕所用的颜色
    glShadeModel(GL_SMOOTH);   // 平滑方式,这也是默认方式
    glClearDepth(1.0);//设置深度缓存
    glEnable(GL_DEPTH_TEST);  // 启用深度测试
    glDepthFunc(GL_LEQUAL);  //设置深度测试类型

    glEnable(GL_BLEND);                         //开启混合
    glDisable(GL_DEPTH_TEST);                   //关闭深度测试
    glColor4f(1.0f, 1.0f, 0.0f, 0.5f);                  //50%Alpha混合
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);                  //基于源像素alpah通道值得半透明混合函数
}

运行结果:

这里写图片描述

代码下载
OpenGL学习系列导航

简单的透明 OpenGL中的绝大多数特效都与某些类型的(色彩)混合有关。混色的定义为,将某个象素的颜色和已绘制在屏幕上与其对应的象素颜色相互结合。至于如何结合这两个颜色则依赖于颜色的alpha通道的分量值,以及/或者所使用的混色函数。Alpha通常是位于颜色值末尾的第4个颜色组成分量。前面这些课我们都是用GL_RGB来指定颜色的三个分量。相应的GL_RGBA可以指定alpha分量的值。更进一步,我们可以使用glColor4f()来代替glColor3f()。 绝大多数人都认为Alpha分量代表材料的透明度。这就是说,alpha值为0.0时所代表的材料是完全透明的。alpha值为1.0时所代表的材料则是完全不透明的。 混色的公式 若您对数学不感冒,而只想看看如何实现透明,请跳过这一节。若您想深入理解(色彩)混合的工作原理,这一节应该适合您吧。『译者注:其实并不难^-^。原文中的公式如下,CKER再唠叨一下吧。其实混合的基本原理是就将要分色的图像各象素的颜色以及背景颜色均按照RGB规则各自分离之后,根据-图像的RGB颜色分量*alpha值+背景的RGB颜色分量*(1-alpha值)-这样一个简单公式来混合之后,最后将混合得到的RGB分量重新合并。』 公式如下: (Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da) OpenGL按照上面的公式计算这两个象素的混色结果。小写的s和r分别代表源象素和目标象素。大写的S和D则是相应的混色因子。这些决定了您如何对这些象素混色。绝大多数情况下,各颜色通道的alpha混色值大小相同,这样对源象素就有 (As, As, As, As),目标象素则有1, 1, 1, 1) - (As, As, As, As)。上面的公式就成了下面的模样: (Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As + Ad (1 - As)) 这个公式会生成透明/半透明的效果。 OpenGL中的混色 在OpenGL中实现混色的步骤类似于我们以前提到的OpenGL过程。接着设置公式,并在绘制透明对象时关闭写深度缓存。因为我们想在半透明的图形背后绘制 对象。这不是正确的混色方法,但绝大多数时候这种做法在简单的项目中都工作的很好。 Rui Martins 的补充: 正确的混色过程应该是先绘制全部的场景之后再绘制透明的图形。并且要按照与深度缓存相反的次序来绘制(先画最远的物体)。 考虑对两个多边形(1和2)进行alpha混合,不同的绘制次序会得到不同的结果。(这里假定多边形1离观察者最近,那么正确的过程应该先画多边形2,再画多边形1。正如您再现实中所见到的那样,从这两个<透明的>多边形背后照射来的光线总是先穿过多边形2,再穿过多边形1,最后才到达观察者的眼睛。) 在深度缓存启用时,您应该将透明图形按照深度进行排序,并在全部场景绘制完毕之后再绘制这些透明物体。否则您将得到不正确的结果。我知道某些时候这样做是很令人痛苦的,但这是正确的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值