丢弃片段
- 在此之前处理的都是rgb三个通道的数据,第四个通道a存储的是物体的透明度
- stb_image在纹理有透明通道的时候会自动加载,但是我们需要在生成纹理过程中告诉openGl,我们的纹理现在使用alpha通道了
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
- OpenGL并不知道如何对alpha通道进行处理,因此需要我们手动来弄,比如当透明度小于某个阈值的时候将这个片段丢弃
vec4 texColor = texture(texture1, TexCoords);
if(texColor.a < 0.1)
discard;
FragColor = texColor;
渲染半透明时的顺序问题
- 如果我们利用深度测试来渲染物体,那么两个半透明物体,比较远的物体如果在靠后渲染会无法通过深度测试然后将片段丢弃。结果导致较近透明物体颜色直接将其覆盖,没有办法显示出后面物体颜色
- 所以应该将所有的半透明物体按照距离远近进行排序,先绘制比较远的物体,然后绘制近处的物体
- 这样绘制出较远物体之后,按照深度缓冲,近处物体能够通过,并且也可以顺利进行混合
- 对于普通不需要混合的物体则任然可以使用深度缓冲正常绘制
- 当绘制一个有不透明和透明物体的场景的时候,大体的原则如下:
- 先绘制所有不透明的物体。
- 对所有透明的物体排序。
- 按顺序绘制所有透明的物体。
为什么是这个顺序
- 不透明物体会遮挡所有物体,因此先绘制他们,深度缓冲放置的就是他们的深度数据
- 然后半透明物体有两种情况,可能会在其前面,也可能在其后面,在后面的因为深度缓冲测试被直接丢弃
- 在前面的可以通过测试,然后混合颜色
- 半透明物体和半透明物体之间则排列顺序,然后渲染
后记
-
虽然按照距离排序物体这种方法对我们这个场景能够正常工作,但它并没有考虑旋转、缩放或者其它的变换,奇怪形状的物体需要一个不同的计量,而不是仅仅一个位置向量。
-
在场景中排序物体是一个很困难的技术,很大程度上由你场景的类型所决定,更别说它额外需要消耗的处理能力了。完整渲染一个包含不透明和透明物体的场景并不是那么容易。
疑惑
- 片段着色器运行完成后,并且所有的测试都通过之后,这个混合方程(Blend Equation)才会应用到片段颜色输出与当前颜色缓冲中的值(当前片段之前储存的之前片段的颜色)上
- 混合是在最靠后的
- 我想知道为什么是这个顺序,先片段着色器运行,然后是模板测试,再其次是深度测试
- 【模板测试我可以理解,渲染物体来影响模板值,然后通过这些模板值来进一步影响渲染】
- 【可是在顶点着色器进行空间变换的时候,就已经获得每个物体的深度值了,直接根绝这些深度值将某些片段丢掉难道不可以吗?】
- 【而且提前深度测试需要关闭写入深度值,这是为什么】
线性插值
y = (1 − α)y0 + αy1