【问题标题】:Hidden Line Removal algorithm for 3D meshes?3D网格的隐藏线去除算法?
【发布时间】:2011-06-26 16:11:01
【问题描述】:

给定一个任意 3D 网格,我正在寻找一种可以实时执行隐藏线移除的算法。我在 OpenGL 的上下文中工作,这意味着我们可以利用 Z-Buffer。

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

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

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

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

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

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

【问题讨论】:

  • 更新:第一个问题被称为“折痕边缘检测”。第二个问题为“剪影边缘检测”。
  • 是的,轮廓本质上是穿过网格顶点。顺便说一句,定义轮廓顶点的过程是计算“阴影体积”的关键阶段。

标签: opengl graphics geometry


【解决方案1】:

这里发生了几件事。首先,您要绘制网格线,其次要绘制轮廓。这是使这项工作的通用过程,

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

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

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

结果是您现在将绘制网格的所有边缘以及漂亮的轮廓!

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

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

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

【讨论】:

  • Mikola,感谢您的帮助,但这并不能解决我的问题。我知道现有的 OpenGL 技术(涉及多边形偏移或模板缓冲区),但它们仅适用于绘制轮廓。我想要的也是绘制任意模型的相关边缘。以立方体为例。我希望算法告诉我:绘制除对角线以外的所有边...
  • Mikola,感谢您编辑您的答案。您建议“比较点积”。我接受它作为我问题的部分解决方案。我仍然需要找出一种为任意网格定义边(和相关面)的有效方法。也许这应该是另一个问题的主题......
  • 关于你的“近似网格曲率”的提议:听起来很有趣,但它现在有点超出我的技术能力。无论如何,感谢您指向 GDC 2011 文章。绝对是令人兴奋的视觉效果!
【解决方案2】:

这听起来是a lot like cel shading

这就是你要找的吗?

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

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

【讨论】:

  • Erno,感谢您的回答。我对单元格着色的照明方面不感兴趣。然而,我对单元格着色的“简单边缘检测”部分感兴趣,“它使用视图向量和顶点法线之间的点积”。关键是我不打算使用着色器,所以我需要弄清楚如何手动做这种事情。我现在的部分问题是找到一种有效的方法来定义任意网格的边(和相关面)。
  • 干得好,准时!我正要实现一个 Quad-Edge 数据结构来迭代所有的边缘,但是根据你的建议,我肯定会从“影子体积”素养中寻求最终不那么矫枉过正的解决方案。所以再次感谢 Erno(太糟糕了,我不能接受两个答案......)
  • 别担心,不是分数的问题,我们需要答案!
  • Erno 的链接中缺少源代码,所以我提供了一个替代链接,源代码为:archive.gamedev.net/reference/articles/article1990.asp
猜你喜欢
  • 2014-12-15
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 2014-04-29
  • 1970-01-01
相关资源
最近更新 更多