深度测试无法与模板测试一起正常工作
Depth test not working correctly with stencil test
我需要使用模板缓冲区在 3D 表面上切割孔。
目前,一切都按预期进行,但主要问题是在山上也可以看到洞。如果他们在山后,如何防止这种行为并隐藏漏洞?
当前代码:
GLES20.glColorMask(false,false,false,false);
GLES20.glDepthMask(false);
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
GLES20.glStencilFunc(GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);
GLES20.glStencilMask(0xFF);
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
//drawing holes
GLES20.glStencilFunc(GLES20.GL_EQUAL, 0, 0xFF);
GLES20.glStencilMask(0x00);
GLES20.glColorMask(true,true,true,true);
GLES20.glDepthMask(true);
//draw surface with elevation
提供效果的解决方案,可以通过Face Culling by a separated stencil test for front and back faces and (see glStencilFuncSeparate
and glStencilOpSeparate
)实现。
遗憾的是,几何图形的背面必须在单独的步骤中绘制。
该过程可以描述为以下步骤:
启用深度测试
禁用颜色缓冲区并启用模板测试以设置模板掩码
绘制"holes"。这导致模板缓冲区在孔的位置设置为 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)
// ....
我需要使用模板缓冲区在 3D 表面上切割孔。 目前,一切都按预期进行,但主要问题是在山上也可以看到洞。如果他们在山后,如何防止这种行为并隐藏漏洞?
当前代码:
GLES20.glColorMask(false,false,false,false);
GLES20.glDepthMask(false);
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
GLES20.glStencilFunc(GLES20.GL_ALWAYS, 1, 0xFF);
GLES20.glStencilOp(GLES20.GL_KEEP, GLES20.GL_KEEP, GLES20.GL_REPLACE);
GLES20.glStencilMask(0xFF);
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
//drawing holes
GLES20.glStencilFunc(GLES20.GL_EQUAL, 0, 0xFF);
GLES20.glStencilMask(0x00);
GLES20.glColorMask(true,true,true,true);
GLES20.glDepthMask(true);
//draw surface with elevation
提供效果的解决方案,可以通过Face Culling by a separated stencil test for front and back faces and (see glStencilFuncSeparate
and glStencilOpSeparate
)实现。
遗憾的是,几何图形的背面必须在单独的步骤中绘制。
该过程可以描述为以下步骤:
启用深度测试
禁用颜色缓冲区并启用模板测试以设置模板掩码
绘制"holes"。这导致模板缓冲区在孔的位置设置为 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)
// ....