检测并删除网格的隐藏曲面

时间:2014-07-28 21:24:08

标签: c++ algorithm optimization mesh raytracing

在过去的几周里,我一直在研究一种算法,该算法可以找到复杂网格的隐藏曲面并将其移除。这些隐藏的表面完全被遮挡,永远不会被看到。由于我正在使用的网格的性质,有大量这些隐藏的三角形。在某些情况下,隐藏表面比可见表面更多。由于手动删除它们对于较大的网格来说是禁止的,我希望用软件自动执行此操作。

我目前的算法包括:

  1. 在三角形表面上生成多个点。
  2. 对于每个点,生成一个与三角形法线对齐的半球采样器。
  3. 将光线投射到半球中。
  4. 如果未遮挡的光线数量少于一定数量,我会将三角形标记为删除。
  5. 然而,这种算法引起了很多悲痛。这是非常不一致的。虽然算法没有发现一些“被遮挡”的面被遮挡,但我更担心由于当前实现的问题而被删除的非常明显的面。因此,我想知道两件事,主要是:

    1. 有没有比光线追踪更好的方法来查找和删除这些隐藏的表面?
    2. 我应该调查非随机光线生成吗?我目前正在余弦加权半球中生成随机方向,这可能会导致问题。我没有调查过的唯一原因是因为我还没有找到一种算法来在半球中生成均匀间隔的光线。
    3. 注意:这是一个对象空间算法。也就是说,可以从任何角度看 - 而不是固定的摄像头。

2 个答案:

答案 0 :(得分:2)

我实际上从未实现过光线跟踪,但无论如何我都有一些建议。由于您的目标是检测每个隐藏的三角形,您可以转动问题,而不是找到每个可见的三角形。

我正在考虑以下两种方式:

  1. 从外部和朝向中心/垂直于表面的光线轨迹,将任何三角形标记为可见。
  2. 剔除所有其他人。
    1. 选择模型视图。
    2. 栅格化模型(例如,为每个三角形使用不同的颜色)。
    3. 将任何可见的三角形标记为可见。
    4. 更改方向并重复。
    5. 剔除所有不可见的三角形。
    6. 最后一个优点是,如果可以可靠地读/写像素,使用图形API实现它应该相对便宜。

      两者的缺点是需要的分辨率。不应该剔除的小开口内的三角形可能仍然是,因此光线的数量可能是禁止的(在第一种算法中)或者你将需要非常大的屏幕外帧缓冲区(在第二种中)。

答案 1 :(得分:1)

可能有所帮助的一些想法。

  1. 使用连接测试确定连接到主模型的内容(如果有)。
  2. 使用Depth Peeling的变体(我已经用它将贝壳转换为体素;一旦你知道要保留的模型里面有什么(体素),你可以将你想要的垃圾交叉删除。)
  3. 创建连接图并根据连接组的复杂性修剪图表。