混合

来源:互联网 发布:中国第五人口普查数据 编辑:程序博客网 时间:2024/06/09 20:18

Learn Opengl

       在OpenGL中,物体透明技术通常被叫做混合(Blending)一个物体的透明度,被定义为它的颜色的alpha值。alpha颜色值是一个颜色向量的第四个元素。


       我们之前所使用的纹理都是由3个颜色元素组成的:红、绿、蓝,但是有些纹理同样有一个内嵌的aloha通道,它为每个纹理像素(Texel)包含着一个alpha值。这个alpha值告诉我们纹理的哪个部分有透明度,以及这个透明度有多少。例如,下面图片玻璃部分的alpha值为0.25(它的颜色是完全红色,但是由于它有75的透明度,它会很大程度上反映出网站的背景色,看起来就不那么红了),角落部分alpha是0.0。



为了渲染出不同的透明度级别,我们需要开启混合(Blending)。像大多数OpenGL的功能一样,我们可以开启GL_BLEND来启用混合(Blending)功能:

glEnable(GL_BLEND);

开启混合后,我们还需要告诉OpenGL它该如何混合。OpenGL以下面的方程进行混合:


  • C¯source:源颜色向量。这是来自纹理的本来的颜色向量。
  • C¯destination:目标颜色向量。这是储存在颜色缓冲中当前位置的颜色向量。
  • Fsource:源因子。设置了对源颜色的alpha值影响。
  • Fdestination:目标因子。设置了对目标颜色的alpha影响。

片段着色器运行完成并且所有的测试都通过以后,混合方程才能自由执行片段的颜色输出,当前它在颜色缓冲中(前面片段的颜色在当前片段之前储存)。源和目标颜色会自动被OpenGL设置,而源和目标因子可以让我们自由设置。我们来看一个简单的例子:

我们有两个方块,我们希望在红色方块上绘制绿色方块。红色方块会成为目标颜色(它会先进入颜色缓冲),我们将在红色方块上绘制绿色方块。

我们怎样来设置因子呢?我们起码要把绿色方块乘以它的alpha值,所以我们打算把Fsrc设置为源颜色向量的alpha值:0.6。接着,让目标方块的浓度等于剩下的alpha值。如果最终的颜色中绿色方块的浓度为60%,我们就把红色的浓度设为40%(1.0 – 0.6)。所以我们把Fdestination设置为1减去源颜色向量的alpha值。方程将变成:


最终方块结合部分包含了60%的绿色和40%的红色,得到一种脏兮兮的颜色:

最后的颜色被储存到颜色缓冲中,取代先前的颜色。

这个方案不错,但我们怎样告诉OpenGL来使用这样的因子呢?恰好有一个叫做glBlendFunc的函数。

void glBlendFunc(GLenum sfactor, GLenum dfactor)接收两个参数,来设置源(source)和目标(destination)因子。OpenGL为我们定义了很多选项,我们把最常用的列在下面。

选项值GL_ZERO0GL_ONE1GL_SRC_COLOR源颜色向量C¯sourceGL_ONE_MINUS_SRC_COLOR1C¯sourceGL_DST_COLOR目标颜色向量C¯destinationGL_ONE_MINUS_DST_COLOR1C¯destinationGL_SRC_ALPHAC¯sourcealpha值GL_ONE_MINUS_SRC_ALPHA1 C¯sourcealpha值GL_DST_ALPHAC¯destinationalpha值GL_ONE_MINUS_DST_ALPHA1 C¯destinationalpha值GL_CONSTANT_COLOR常颜色向量C¯constantGL_ONE_MINUS_CONSTANT_COLOR1C¯constantGL_CONSTANT_ALPHAC¯constantalpha值GL_ONE_MINUS_CONSTANT_ALPHA1 C¯constantalpha为从两个方块获得混合结果,我们打算把源颜色的alpha给源因子,1alpha给目标因子。调整到glBlendFunc之后就像这样:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

OpenGL给了我们更多的自由,我们可以改变方程源和目标部分的操作符。现在,源和目标元素已经相加了。如果我们愿意的话,我们还可以把它们相减。

void glBlendEquation(GLenum mode)允许我们设置这个操作,有3种可行的选项:

  • GL_FUNC_ADD:默认的,彼此元素相加:C¯result=Src+Dst
  • GL_FUNC_SUBTRACT:彼此元素相减: C¯result=SrcDst
  • GL_FUNC_REVERSE_SUBTRACT:彼此元素相减,但顺序相反:C¯result=DstSrc.

通常我们可以简单地省略glBlendEquation因为GL_FUNC_ADD在大多数时候就是我们想要的,但是如果你如果你真想尝试努力打破主流常规,其他的方程或许符合你的要求。



0 0