【问题标题】:How to render a mesh behind another mesh, like a mask?如何在另一个网格后面渲染网格,例如蒙版?
【发布时间】:2013-09-18 16:07:23
【问题描述】:

我希望当网格 A(角色)在网格 B(一堵墙)后面时,它仍然会被渲染,但使用纯灰色。

我正在开始使用 opengles 2.0,但我仍然不确定是否要解决这个问题。据我了解,深度缓冲区允许网格物体在它们包含的片段中看到谁,还有可能涉及到的各种混合功能,最后模板缓冲区看起来也具有这种理想的功能。

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

什么是这项技术以供将来参考?我在很多视频游戏中都看到过它。

【问题讨论】:

    标签: c++ opengl-es opengl-es-2.0 shader


    【解决方案1】:

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

    代码

    我强烈建议您深入了解模板测试单元的文档。这是一个非常强大的机制,但经常被忽视。您的特定问题将通过以下方式解决。我建议您使用此示例代码,将其与模板测试功能参考glStencilFuncglStencilOp 并行阅读。

    您必须将模板缓冲区添加到帧缓冲区的像素格式中——具体操作方式取决于平台。例如,如果您使用 GLUT,那么您需要将 |GLUT_STENCIL 添加到 glutInitDisplayMode 的格式位掩码中;在 iOS 上,你会在 GLKView 上设置一个属性;等等。一旦你添加了一个模板缓冲区,你应该通过在每个绘图的初始 glClear 调用中添加 |GL_STENCIL_BUFFER_BIT 来清除它以及其他渲染缓冲区。

    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();
    
        /* ... */
    }
    

    【讨论】:

    • 不错的答案。添加了一些平台注释,因为 OP 没有说明他在哪个平台上,并且当您使用 OpenGL ES 而不是桌面时,更担心平台细节。
    • @rickster:您必须在原生 Windows 或 GLX 或使用 EGL 时,在设置像素格式时涵盖这些细节。
    猜你喜欢
    • 2019-11-12
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多