深度测试与模板测试无法正常工作

时间:2018-04-10 15:20:44

标签: android graphics opengl-es stencil-buffer depth-testing

我需要使用模板缓冲区在3D表面上切孔。 目前,一切都按预期工作,但主要问题是通过山丘也可以看到洞。如果他们在山后面,如何防止这种行为并隐藏漏洞?

当前代码:

const SetRuc = (num) => {
  for (let i = 1; i <= num; i++) { 
    (i % 3 === 0) ? console.log('Set')
    (i % 5 === 0) ? console.log('Ruc')
    (i % 3 === 0 && i % 5 === 0) ? console.log('SetRuc') : console.log(i)
  }
}

SetRuc(100)

enter image description here

1 个答案:

答案 0 :(得分:1)

提供效果的解决方案可以通过Face Culling通过前后面的分离模板测试来实现(参见glStencilFuncSeparateglStencilOpSeparate)。 遗憾的是,几何体的背面必须分开绘制。

可以按以下步骤描述该过程:

  • 启用深度测试

  • 禁用颜色缓冲区并启用模板测试以设置模板蒙版

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

  • 设置模板测试以通过背面清除模板掩模

  • 启用正面的面部剔除

  • 绘制几何体。这会导致模板缓冲区在被覆盖的位置被清除。

  • 启用背面剔除

  • 启用颜色缓冲区

  • 绘制几何

要使算法工作,您必须以相同的绕组顺序绘制所有基元。你必须告诉OpenGL方向 由glFrontFace。 顺时针GL_CW或逆时针GL_CCW

GLES20.glStencilMask(0xFF);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);

GLES20.glFrontFace(GLES20.GL_CCW);  // depends on your geometry "GL_CCW" or "GL_CW"
GLES20.glDisable(GLES20.GL_CULL_FACE);

GLES20.glEnable(GLES20.GL_DEPTH_TEST);
GLES20.glDepthFunc(GLES20.GL_LESS); // default

GLES20.glColorMask(false,false,false,false);

GLES20.glEnable(GLES20.GL_STENCIL_TEST);

GLES20.glStencilFuncSeparate(GLES20.GL_FRONT, GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilFuncSeparate(GLES20.GL_BACK, GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_FRONT, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);
GLES20.glStencilOpSeparate(GLES20.GL_BACK, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP);

// draw the holes
// ....

GLES20.glStencilFuncSeparate(GLES20.GL_FRONT, GLES20.GL_EQUAL, 0, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_FRONT, GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_KEEP);
GLES20.glStencilFuncSeparate(GLES20.GL_BACK, GLES20.GL_ALWAYS, 0, 0xFF);
GLES20.glStencilOpSeparate(GLES20.GL_BACK, GLES20.GL_KEEP, GLES20.GL_KEEP, GL_REPLACE);

GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glCullFace(GLES20.GL_FRONT);

// draw the geometry the 1. time ("draw" back faces)
// ....

GLES20.glCullFace(GLES20.GL_BACK);
GLES20.glColorMask(true,true,true,true);

// draw the geometry the 2. time (draw front faces)
// ....