8

我正在制作一个简单的体素引擎(想想 Minecraft),目前正处于摆脱遮挡面以获得一些宝贵的 fps 的阶段。我在 OpenGL 中的实验并不多,也不太了解 glColorMask 魔法是如何工作的。

这就是我所拥有的:

// new and shiny
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// this one goes without saying
glEnable(GL_DEPTH_TEST);

// I want to see my code working, so fill the mask
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

// fill the z-buffer, or whatever
glDepthFunc(GL_LESS);
glColorMask(0,0,0,0);
glDepthMask(GL_TRUE);

// do a first draw pass
world_display();

// now only show lines, so I can see the occluded lines do not display
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

// I guess the error is somewhere here
glDepthFunc(GL_LEQUAL);
glColorMask(1,1,1,1);
glDepthMask(GL_FALSE);

// do a second draw pass for the real rendering
world_display();

这有点奏效,但是一旦我改变相机位置,世界开始消失,我看到的线条越来越少,直到什么也没有。

4

3 回答 3

10

听起来您没有清除深度缓冲区。

glDepthMask(GL_TRUE);当您尝试使用 清除深度缓冲区时,您需要启用深度写入(通过) glClear。您可能仍然从前一帧禁用它,导致您的所有清除在后续帧中都是无操作的。只需将您的glDepthMask电话移到glClear.

于 2010-12-26T13:02:28.323 回答
8

glColorMask 和 glDepthMask 确定实际写入帧缓冲区的哪些部分。

早期 Z 剔除的想法是,首先只渲染深度缓冲区部分——实际节省来自对几何图形进行从近到远的排序,以便 GPU 可以快速丢弃被遮挡的片段。然而,在绘制 Z 缓冲区时,您不想绘制颜色分量:这允许您切换着色器、纹理,即简而言之,所有计算密集型的东西。

一句警告:Early Z 仅适用于不透明几何。实际上整个深度缓冲算法只适用于不透明的东西。一旦你进行混合,你就必须从远到近排序,不要使用深度缓冲(搜索“顺序无关透明度”算法来克服相关问题)。

S 如果您有任何混合的东西,请将其从“早期 Z”阶段中删除。

在你设置的第一遍

glDepthMask(1); // enable depth buffer writes
glColorMask(0,0,0); // disable color buffer writes
glDepthFunc(GL_LESS); // use normal depth oder testing
glEnable(GL_DEPTH_TEST); // and we want to perform depth tests

Z pass 完成后,您可以稍微更改设置

glDepthMask(0); // don't write to the depth buffer
glColorMask(1,1,1); // now set the color component

glDepthFunc(GL_EQUAL); // only draw if the depth of the incoming fragment
                       // matches the depth already in the depth buffer

GL_LEQUAL 也可以完成这项工作,但也可以让片段比深度缓冲区中的片段更接近。但是由于没有更新深度缓冲区,所以每次在原点和存储的深度之间绘制的东西都会覆盖它。

主题的一个细微变化是在之后的多个延迟着色通道中使用“早期 Z”填充深度缓冲区作为几何缓冲区。

要保存更多几何图形,请查看Occlusion Queries。通过遮挡查询,您可以询问 GPU 有多少片段(如果有的话)通过了所有测试。这是一个体素引擎,您可能正在使用八叉树或 Kd 树。在遍历树枝之前绘制树枝的空间分割面(使用 glDepthMask(0)、glColorMask(0,0,0))会告诉您,如果该树枝中的任何几何图形完全可见。结合从近到远排序的遍历和树上的(粗)截头截头体剪裁将为您带来巨大的性能优势。

于 2010-12-26T11:37:51.740 回答
5

z-pre pass 可以处理半透明物体。如果它们是半透明的,不要在 prepass 中渲染它们,然后 zsort 和渲染。

于 2011-06-21T22:03:32.633 回答