三维网格的隐藏线移除算法?

时间:2011-06-25 21:15:33

标签: opengl graphics geometry

鉴于任意3D网格,我正在寻找一种能够实时执行隐藏线删除的算法。我在OpenGL环境中工作,这意味着我们可以利用Z-Buffer。

我想该算法应该包含以下两个问题的解决方案:

1)定义哪些是“硬边缘”,以便稍后使用常规OpenGL线绘制它们。这些“硬边缘”应该对应于两个相应面之间的角度高于某个阈值的边缘。

为简单起见,让我们声明保证每条边不超过2个面。

每个网格应该进行一次“硬边”的计算,即它与视点无关。

2)根据当前视点定义网格轮廓的轮廓。最终,这部分可以使用经典的OpenGL技术(涉及多边形偏移或模板缓冲)来完成,但最好使用常规OpenGL线绘制轮廓,以保持统一的外观和放大。感觉所有的线条。

对于那部分,我不确定轮廓的顶点是否都应该通过网格顶点。在任何情况下,对于像立方体这样的网格,其中不需要轮廓(因为它足以仅绘制“硬边缘”)_算法应该足够智能以避免两次绘制“相似的线”。

2 个答案:

答案 0 :(得分:4)

这里有几件事情要发生。首先,你想绘制网格线,然后你想绘制一个轮廓。这是使这项工作的通用程序,

  1. 仅通过清除color mask将(使用三角形)网格绘制到深度缓冲区。

  2. 重新打开颜色遮罩,切换front face,然后将网格重新缩放/偏移一些小百分比。翻转正面使您只能看到偏移网格的内部,该网格会被先前绘制的网格的深度缓冲区剪切。如果你这样做,它应该给你一个整洁的轮廓。以下是此技术的示例:http://www.codeproject.com/KB/openGL/Outline_Mode.aspx

  3. 最后,在现有网格和外壳上绘制网格边缘(同时保持深度缓冲区与前两个操作完好无损)。

  4. 结果是,您现在将绘制网格的所有边缘,并且具有漂亮的轮廓!

    编辑:第二次重新阅读你的帖子后,听起来你不想绘制所有边缘,只有那些出现在曲率足够高的边界的边缘。因此,要执行此操作,您可以执行以下操作之一:

    1. 预处理网格边缘,并剔除连接几乎共面面对的所有边。通过比较法线的点积可以很容易地检查。如果它足够接近1,则从渲染集中丢弃该边缘。

    2. 更一般地说,您还可以在屏幕空间中近似网格的曲率。这样做是计算所谓的屏幕空间环境遮挡的反过来。 (此处列出了此技术的另一个巧妙应用:http://zigguratvertigo.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/)一旦从深度缓冲区计算了对象的曲率,就可以通过仅绘制出现在像素上的线段来过滤掉线条曲率。

答案 1 :(得分:1)

这听起来a lot like cel shading

这就是你要找的东西吗?

诀窍是去除钝的边缘。棘手的部分是使阈值正确,每个对象可能不同。

This article explains more about the algorithm一般来说,它是最快的to implement the effect using a pixel shader