首页 > 解决方案 > 将 SDF 计算为三角形网格的最有效方法

问题描述

来自三角形、边和顶点的 SDF

你好。

在过去的一个月里,我一直在从各种来源收集信息,但没有找到适合我特定问题的想法。所以这是问题的表述:

给定一个缓冲区几何形式的网格(顶点坐标和顶点索引的 32 位数组 + 附加数组,例如顶点法线、uvs 或切线),计算一个均匀网格周围点的有符号距离函数 (SDF)几何学。

更具体地说,我打算在 Maxon 的 Cinema4D 或 Blender 等 3D 引擎中创建类似于 MetaBall 对象的东西。我已经成功地为所有几何图元实现了距离函数,但是任意网格 SDF 要求我实现蛮力方法 - 为每个网格点测试网格的每个三角形的距离 - 当然,对于复杂的网格。

现在,我回忆起这些问题中的大多数都需要构建树状结构,例如八叉树、KD-tree、BSP-tree 或 AABB-tree。然后我发现了一些关于所谓的快速扫描算法 (用于求解 Eikonal 方程)的文章,它需要首先用 0 填充位于边界上的网格点(在我的情况下是网格,或最接近网格)剩下的具有较大的值(Infinity),然后迭代求解非线性双曲边值问题(Gauss-Seidel)。我还在CGAL 库中找到了网格 SDF 方法的开源实现。或者,我也考虑过使用一些着色器库(如 GLSL),也许尝试使用 GPU 构建树,但我从未在 JS 或 TS 项目中使用过着色器。

我一直坚持的步骤不仅是选择最佳选项,而且实际上是有效地使用这些方法中的至少一种。例如:

我考虑过结合多种方法,但这一切似乎都非常耗时。我也想过使用 CGAL 库,或者为了我的项目而重构它,但我发现由于库中的所有依赖项,很难理解 C++ 代码。你们中有人做过类似的事情吗?你会推荐什么?

感谢您的所有见解。

标签: typescriptthree.jseuclidean-distanceaabbmarching-cubes

解决方案


我使用三(四)个主要步骤概述的方法解决了这个问题:

  1. 生成网格三角形汤的 AABB 树

  2. 每当立方体与网格相交(使用 AABB 树的快速相交)形成八叉树时,使用 AABB 树细分常规边界立方体。当细分到达叶子时,计算精确的平方距离(立方体质心到三角形)并取最小的平方根,将其写入基于立方体最小-最大坐标的规则网格。

  3. 使用网格相交体素上的精确距离值和其他地方的较大值,运行快速扫描算法 8 次并用距离值填充标量网格。

  4. (可选)洪水填充否定距离网格的外部体素,以确保标记的初始体素(具有精确值)轮廓内的体素具有负号(不幸的是,这是分辨率 > 100^3 的网格最慢的部分)

要更详细地了解我的计算时间实现,请随时阅读我的​​博客文章: https ://mshgrid.com/blog/

感谢您的支持和评论:)。


推荐阅读