透明物体
之前一直未介绍透明物体,但是在现实生活中,透明物体或者半透明物体随处可见,但是透明物体往往有很多与众不同之处,比如,在OpenGL中,透明物体不能写入深度,原因可以想一下,对于透明物体和不透明物体组合有两种形式:
- 如果一个透明物体在一个不透明物体之前,那么理论上,如果写入深度值,那么后面的不透明物体将不可见,但实际是我们可以通过透明物体看到后面的东西
- 如果一个透明物体在一个不透明物体之后,透明物体将不可见
- 对于第一种情况,为了模拟能看到透明物体后面的东西,同时要看到透明物体,那么就需要对重合部分的颜色进行混合计算。
这意味着透明物体要关闭深度写入,要是要开启深度测试,同时开启混合算法
为了能看到透明物体后面的内容,需要进行混合
深度测试在之前有介绍
窗户的例子(图片选自LearnOpenGL):
混合
对于需要混合的物体有以下要求:
带有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);
混合实例——以下两张图片进行混合后,交叉部分将会展现新的颜色:
混合函数:
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技术,透明物体则从后向前渲染,因为透明物体需要和后面的物体进行叠加,同时不写入深度值,暂且简单介绍一下,之后会有相关文章详细介绍。
要想让混合在多个物体上工作,我们需要最先绘制最远的物体,最后绘制最近的物体。普通不需要混合的物体仍然可以使用深度缓冲正常绘制,所以它们不需要排序。但我们仍要保证它们在绘制(排序的)透明物体之前已经绘制完毕了。当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:
- 先绘制所有不透明的物体。从近到远
- 对所有透明的物体排序。从远到近
- 按顺序绘制所有透明的物体。