如何在另一个网格后面渲染网格,就像面具一样?

1 c++ shader opengl-es opengl-es-2.0

我想这样,当网格A(角色)位于网格B(墙壁)后面时,它仍然呈现但是具有纯灰色.

我正在开始使用opengles 2.0,我仍然不确定是否会这样做.根据我的理解深度缓冲区允许网格战斗谁将在他们所包含的片段中看到,也有各种可能涉及的混合函数,最后模板缓冲区看起来它也将具有这种理想的功能.

那么有没有办法根据失败的深度测试通过着色器输出不同的颜色?有没有办法通过混合来做到这一点?或者我必须如何使用模板缓冲区?

什么是这种技术需要将来参考?我已经看到它用在很多电子游戏中.

dat*_*olf 5

这可以使用模板缓冲区完成.模板缓冲器为每个像素提供一些额外的位,可用作位掩码或计数器.在您的情况下,您将配置模板测试单元以在角色的深度测试失败时设置特定的位掩码(因为它被井阻塞).然后切换模板测试模式操作以通过此特定位掩码的模板测试,并以所需颜色渲染完整视口,实心四边形,并禁用深度测试和深度写入.

我强烈建议您深入了解模板测试单元的文档.这是一个非常强大的机制,经常被忽视.您的特定问题将通过以下方式解决.我觉得你拿这个例子代码,与模板测试函数并行读取glStencilFunc,glStencilOp.

您必须为帧缓冲区的像素格式添加模板缓冲区 - 您如何做到这一点与平台有关.例如,如果您正在使用GLUT,那么您将添加|GLUT_STENCIL到格式的位掩码glutInitDisplayMode; 在iOS上你要设置一个属性GLKView; 一旦添加了模板缓冲区,就应该通过添加每个绘图|GL_STENCIL_BUFFER_BIT的初始glClear调用将其与其他渲染缓冲区一起清除.

GLint const silouhette_stencil_mask = 0x1;

void display()
{
    /* ... */    

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

    glDisable(GL_STENCIL_TEST);
    /* The following two are not necessary according to specification.
     * But drivers can be buggy and this makes sure we don't run into
     * issues caused by not wanting to change the stencil buffer, but
     * it happening anyway due to a buggy driver.
     */
    glStencilFunc(GL_NEVER, 0, 0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    draw_the_wall();

    glEnable(GL_STENCIL_TEST);
    glStencilFunc(GL_ALWAYS, silouhette_stencil_mask, 0xffffffff);
    glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);

    draw_the_character();

    glStencilFunc(GL_EQUAL, silouhette_stencil_mask, 0xffffffff);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);

    draw_full_viewport_solid_color();

    /* ... */
}
Run Code Online (Sandbox Code Playgroud)