OpenGL学习笔记十四(处理半透明物体)

OpenGL学习笔记十四(处理半透明物体)

  • 透明物体
  • 混合
  • 渲染顺序

透明物体

之前一直未介绍透明物体,但是在现实生活中,透明物体或者半透明物体随处可见,但是透明物体往往有很多与众不同之处,比如,在OpenGL中,透明物体不能写入深度,原因可以想一下,对于透明物体和不透明物体组合有两种形式:

  1. 如果一个透明物体在一个不透明物体之前,那么理论上,如果写入深度值,那么后面的不透明物体将不可见,但实际是我们可以通过透明物体看到后面的东西
  2. 如果一个透明物体在一个不透明物体之后,透明物体将不可见
  3. 对于第一种情况,为了模拟能看到透明物体后面的东西,同时要看到透明物体,那么就需要对重合部分的颜色进行混合计算。

这意味着透明物体要关闭深度写入,要是要开启深度测试,同时开启混合算法
为了能看到透明物体后面的内容,需要进行混合
深度测试在之前有介绍
窗户的例子(图片选自LearnOpenGL):
OpenGL学习笔记十四(处理半透明物体)_第1张图片

混合

对于需要混合的物体有以下要求:
带有Alpha值的物体,透明度由Alpha值控制(0-1),即颜色类型位RGBA
因此在使用带透明度的贴图时应该如下的指定方式,同时注意图片格式,如jpg就不行,在之前有介绍

使用stb_image.h

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

OpenGL开启混合:

glEnable(GL_BLEND);

混合实例——以下两张图片进行混合后,交叉部分将会展现新的颜色:
OpenGL学习笔记十四(处理半透明物体)_第2张图片
OpenGL学习笔记十四(处理半透明物体)_第3张图片
混合函数:

result=source∗Fsource+destination∗Fdestination

  • source:源颜色向量。这是源自纹理的颜色向量。
  • destination:目标颜色向量。这是当前储存在颜色缓冲中的颜色向量。
  • Fsource: 源因子值。指定了alpha值对源颜色的影响。实例中为红色(1)
  • Fdestination: 目标因子值。指定了alpha值对目标颜色的影响。实例中为绿色(0.6)
glBlendFunc(GLenum sfactor, GLenum sfactor)

公式与插值相似
Fsource和Fdestination的值为以下选项:

选项
GL_ZERO 因子等于0,舍去对应的贴图
GL_ONE 因子等于1,全取
GL_SRC_COLOR 因子等于源颜色向量source
GL_ONE_MINUS_SRC_COLOR 因子等于1−C¯source
GL_DST_COLOR 因子等于目标颜色向量C¯destination
GL_ONE_MINUS_DST_COLOR 因子等于1−C¯destination
GL_SRC_ALPHA 因子等于C¯source的alpha分量
GL_ONE_MINUS_SRC_ALPHA 因子等于1− C¯source的alpha分量
GL_DST_ALPHA 因子等于C¯destination的alpha分量
GL_ONE_MINUS_DST_ALPHA 因子等于1− C¯destination的alpha分量
GL_CONSTANT_COLOR 因子等于常数颜色向量C¯constant
GL_ONE_MINUS_CONSTANT_COLOR 因子等于1−C¯constant
GL_CONSTANT_ALPHA 因子等于C¯constant的alpha分量
GL_ONE_MINUS_CONSTANT_ALPHA 因子等于1− C¯constant的alpha分量

一般选则为:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

也可以使用glBlendFuncSeparate为RGB和alpha通道分别设置不同的选项

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);

渲染顺序

渲染顺序在做优化上非常重要,比如不透明物体应该从前向后的顺序渲染,因为深度值越大,越容易不被遮挡,这里涉及Early-Z技术,透明物体则从后向前渲染,因为透明物体需要和后面的物体进行叠加,同时不写入深度值,暂且简单介绍一下,之后会有相关文章详细介绍。
要想让混合在多个物体上工作,我们需要最先绘制最远的物体,最后绘制最近的物体。普通不需要混合的物体仍然可以使用深度缓冲正常绘制,所以它们不需要排序。但我们仍要保证它们在绘制(排序的)透明物体之前已经绘制完毕了。当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:

  1. 先绘制所有不透明的物体。从近到远
  2. 对所有透明的物体排序。从远到近
  3. 按顺序绘制所有透明的物体。

你可能感兴趣的:(OpenGL)