0

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

更具体地说:假设我们要渲染四个三角形。应该在三角形 1 和 2之间以及三角形 3 和 4之间启用深度测试,但既不三角形 1 和 3之间, 也不在 三角形 2 和 4之间。

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

根据opengl.org 常见问题解答(参见页面底部 - 12.080),可以为此目的将场景划分为多个区域,但描述并没有足够详细,我无法理解这是如何实现的。

4

2 回答 2

1

我想到了几种可能性。

每帧多次清除深度缓冲区

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

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

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

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

于 2015-07-23T04:20:48.273 回答
0

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

于 2015-07-22T21:31:40.327 回答