提问人:BENG 提问时间:10/13/2023 更新时间:10/13/2023 访问量:25
在 OpenGL 中剔除人脸后面的线条
Culling lines behind a face in OpenGL
问:
我目前的任务是渲染 3D 网格的面,并将边缘渲染为粗线(粗细可变)。但是我想对被人脸遮挡的线条执行隐藏线删除。
过去,我只是在渲染人脸时实现了多边形偏移,这就足够了。我没有得到任何 z 战斗。但是,现在我正在完善渲染例程,我需要绘制可变粗细的线条。我目前让我的线通过一个几何着色器,该着色器将每条线变成一个非常细的四边形,其可变。但是,多边形偏移不再有效,尤其是在更高分辨率下。我意识到我只需要剔除任何被面隐藏的线条基元,然后绘制其余的线条,无需深度测试,因此每个片段都完全绘制在面的顶部。
我的问题是我怎样才能像这样进行剔除?但我想在 GPU 上执行此操作,因为在 CPU 上对每个边缘顶点和每个帧上的每个面执行交集测试是一笔疯狂的费用。
---我的解决方案尝试---
我在 GPU 上剔除线条的引导方法是:
- 将已经具有恒定多边形偏移量的面绘制到帧缓冲区中,并存储 z 值。
- 绘制线条并测试是否不剔除几何着色器中的线条:在每个线顶点的屏幕坐标处对 z 缓冲区进行采样(使用 GL_NEAREST),以测试顶点是否在脸部后面。然后,仅当线的两个端点未被遮挡时,才发出所有四边形顶点。
---分析---
这似乎比 CPU 剔除要好,但我不知道这是否是最好的方法。在几何着色器中使用 if 语句对我来说似乎不太聪明。但话又说回来,它的性能应该不会差多少,因为我认为在大多数情况下,GPU 会执行 if 语句的两个分支来维护 SIMD。但是,如果 if 语句的一个分支什么都不做并且以原始结束,那么我认为它根本不会产生太大的明显影响。
至于边缘情况,我想不出任何会导致不良结果的直接情况(除了多边形偏移问题或两个面彼此非常接近。但无论如何,这都存在于多边形偏移方法中)。它最终起作用,因为无论如何,我们最终都会在像素阶段量化线的端点。在最近的 z 缓冲区处采样(似乎?)等同于此。
这是最佳的吗?有没有更好/更清洁的方法来做到这一点?OpenGL 中是否内置了一种形式的行剔除?
答: 暂无答案
评论