OpenGL选择深度测试

OpenGL selected depth testing

我想实现一个 OpenGL 场景 (OpenGL ES 2.0),其中仅在 选定 个三角形之间启用深度测试。

更具体地说:假设我们有四个三角形要渲染。应在 三角形 1 和 2 之间以及 三角形 3 和 4 之间启用深度测试,但 两者都不[=26] =] 在 三角形 1 和 3 三角形 2 和 4.

之间

换句话说:是否可以在两对三角形内而不是在它们之间启用深度测试(当两对三角形的渲染顺序可以在软件级别更容易计算时提高性能?

根据 opengl.org FAQ(见页面底部 - 12.080),可以为此目的将场景划分为多个区域,但描述不够详细,我无法理解这是如何实现的.

深度测试配置适用于每个绘制调用中的每个三角形;如果您想要不同的设置,则需要进行多次绘制调用。

我想到了几种可能性。

每帧多次清除深度缓冲区

最简单的方法可能是在渲染一组对象后清除深度缓冲区。对于问题中的案例:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw triangle 1.
// Draw triangle 2.
glClear(GL_DEPTH_BUFFER_BIT);
// Draw triangle 3.
// Draw triangle 4.

由于您不会在 1/2 和 3/4 之间进行深度测试,因此如果三角形 3 和 4 重叠,则三角形 3 和 4 将绘制在三角形 1 和 2 的顶部,与它们的相对深度无关。

此解决方案的一个限制是您必须一起绘制每个组的几何图形。例如,如果出于某种原因您要按 1、3、2、4 的顺序渲染三角形,则不能使用此选项。

使用多个深度缓冲区的 FBO 渲染

另一种选择是使用多个深度缓冲区。唯一的方法是使用 FBO 的离屏渲染。在这种情况下,您可以创建多个深度渲染缓冲区。在每次绘制调用之前,您可以将可以使用的深度缓冲区附加到 FBO。

将帧渲染到 FBO 后,您必须将内容复制到默认帧缓冲区。

这样做的好处是,只要每次切换深度缓冲区,您就可以按任何顺序绘制三角形:

glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER, depthBuf1);
// draw triangle 1
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER, depthBuf2);
// draw triangle 3
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER, depthBuf1);
// draw triangle 2
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                          GL_RENDERBUFFER, depthBuf2);
// draw triangle 4

但是,切换渲染缓冲区可能是一项相当昂贵的操作,因此您仍然希望尽量减少切换深度缓冲区的次数。

所以这种方法为您提供了更大的灵活性,但我通常认为它的效率较低。您仍然需要清除所有深度缓冲区,因此您有多个深度清除操作,就像第一种方法一样。此外,您还有切换深度缓冲区的开销,以及将颜色缓冲区复制到帧末尾的默认帧缓冲区的开销。