Opengl es 使用模具测试时会出现奇怪的错误

Opengl es 使用模具测试时会出现奇怪的错误,opengl-es,rendering,opengl-es-2.0,stencil-buffer,Opengl Es,Rendering,Opengl Es 2.0,Stencil Buffer,我正在制作一个应用程序,它显示了一个地形和一些应该插入地形的自定义坑。要将坑插入地形,我使用模板测试。它几乎工作得很好,但存在一些奇怪的bug 代码: glEnable(GL_STENCIL_TEST); glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 255); glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE); glStencilFuncSeparate(GL_BACK, G

我正在制作一个应用程序,它显示了一个地形和一些应该插入地形的自定义坑。要将坑插入地形,我使用模板测试。它几乎工作得很好,但存在一些奇怪的bug

代码:

glEnable(GL_STENCIL_TEST);

glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);

glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);

for (Pit3D* pit in pitList) {
    [pit render];
}

glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_FRONT, GL_REPLACE, GL_KEEP, GL_KEEP);

glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_KEEP);

[terrain render];
错误#1:

glEnable(GL_STENCIL_TEST);

glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);

glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);

for (Pit3D* pit in pitList) {
    [pit render];
}

glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_FRONT, GL_REPLACE, GL_KEEP, GL_KEEP);

glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_KEEP);

[terrain render];
当我穿过小山向深坑望去时,我看到一些奇怪的影子或黑点虽然我从另一座小山望向深坑,但我没有看到阴影或斑点。

Bug#2:

glEnable(GL_STENCIL_TEST);

glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);

glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);

for (Pit3D* pit in pitList) {
    [pit render];
}

glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_FRONT, GL_REPLACE, GL_KEEP, GL_KEEP);

glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_KEEP);

[terrain render];
当凹坑靠近相机时,会出现一些奇怪的像素。 它们肯定属于深坑,但不应该被看见

不幸的是,我现在没有截图。它将在今天晚些时候添加

Bug#3

根据范围和视角,有时凹坑被地形覆盖。但当凹坑靠近摄像机时,凹坑的地形覆盖消失

我不知道如何修复这些错误。请帮帮我。所有答案都将被投票表决

更新:

glEnable(GL_STENCIL_TEST);

glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);

glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 1, 255);
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);

for (Pit3D* pit in pitList) {
    [pit render];
}

glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_FRONT, GL_REPLACE, GL_KEEP, GL_KEEP);

glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0, 255);
glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_KEEP);

[terrain render];
我最近发现凹坑被地形背面覆盖


要实现您想要的效果,您必须从后面到前面绘制场景。注意,在绘制字体面之前,几何体的背面必须清除模具缓冲区

或者使用绘制两次场景。 先绘制场景,然后剔除所有正面;第二次绘制场景,然后剔除所有背面。
对正面和背面使用分离的模具测试,使背面清除模具缓冲区。 (见和)

渲染过程如下所示:

  • 启用深度测试

  • 禁用颜色缓冲区并启用用于设置模具遮罩的模具测试

  • 画“洞”。这导致在孔的位置将模具缓冲区设置为1

  • 设置模具测试以清除模具缓冲区

  • 为正面启用面剔除

  • 绘制几何图形。这会导致在几何体背面覆盖“孔”的位置清除模具缓冲区

  • 为背面启用面剔除

  • 启用颜色缓冲区

  • 绘制几何图形

要使tha算法工作,您必须以相同的缠绕顺序绘制所有基本体。你必须告诉OpenGL方向 通过 顺时针
GL\u-CW
或逆时针
GL\u-CCW


要知道你在做什么几乎是不可能的。请阅读并发布一个完整的例子来重现这个问题。@solidpixel,请告诉我为了更好地理解这个问题你需要知道什么?您需要[terrain render]和[pit render]的代码吗?或者我应该给这个问题添加什么?@solidpixel,我已经更新了代码并添加了我称之为glEnable(GL_STENCIL_TEST)的地方。此外,我还发现凹坑被地形背面覆盖,请参阅更新。