Three.js 加载已经三角剖分的网格是不是比使用四边形的网格更高效?

Posted

技术标签:

【中文标题】Three.js 加载已经三角剖分的网格是不是比使用四边形的网格更高效?【英文标题】:Is it more performant for three.js to load a mesh that's already been triangulated than a mesh using quads?Three.js 加载已经三角剖分的网格是否比使用四边形的网格更高效? 【发布时间】:2020-11-26 18:47:09 【问题描述】:

我读过 Three.js 对所有网格面进行三角测量,对吗?

然后我意识到我一直使用的大多数 gltf 模型都有四面体。在 Blender 中对面进行三角剖分非常容易,所以我很好奇对面进行预三角剖分是否会导致更快的网格加载?

提前致谢,如果您有任何关于three.js 和gltf 的其他性能提示(https://discoverthreejs.com/tips-and-tricks/ 列出的那些提示除外),那将非常有帮助!

【问题讨论】:

【参考方案1】:

glTF 目前的形式不支持四边形,只支持三角形。当前的 glTF 导出器(包括 Blender)在创建 glTF 文件时对模型进行三角测量。有些会在导入时自动尝试将事物重新合并在一起。

根据设计,glTF 以与 WebGL 的顶点属性类似的方式存储其数据,这样它就可以高效地渲染,而只需最少的预处理。但是在创建模型时,您可以做一些事情来帮助它实现这些目标:

尽可能组合材质,以减少绘制调用次数。 尽可能组合网格/基元,以减少绘制调用。 请注意,不连续的法线/UV 会增加顶点数(同样是因为顶点属性)。 避免创建填充纯色的纹理。请改用 Blender 的默认颜色/值节点输入。 保持纹理大小对网络友好,并且是二次方。移动客户端有时无法处理大于 2048x2048 的任何内容。也可以试试 1024x1024 等。

【讨论】:

感谢您的深入和快速的回​​答!几个后续问题:如果混合器在导出为 gltf 时对网格进行三角测量,这意味着面数将比我在混合器中看到的增加,对吗?如果这是真的,blender 的导出器是否以与 triangulate 修改器相同的方式进行三角测量?意思是,我可以使用该修改器来预览导出的网格?当你说“不连续法线/UV增加顶点数”时,不连续是什么意思?我猜紫外线岛是不连续的? 是的,从 Blender 向艺术家展示的内容到 glTF 为 GPU 准备的内容,面数和顶点数都可以增加。我不知道它是否与 triangulate 修饰符完全相同,但我怀疑是这样,如果你关心边缘落在哪里,应用你自己的三角剖分并没有什么坏处。对于“不连续”,想象一个立方体的角,每个 Blender 顶点被 3 个不同的面使用,它们的法线向量非常不同(即,不是平滑着色的)。原始 GPU 数据并不代表像这样具有 3 个不同法线向量的单个顶点,因此顶点将被拆分为 3 个进行渲染。 明白了,这一切都说得通。我在 UV 编辑器中注意到有时(我想当我制作 UV 岛时)我会在 3D 视图中选择 1 个顶点,而在 UV 视图中会选择多个顶点 - 这有点类似于 GPU 顶点数据?是否有针对这些不连续性的高效解决方案? 另外,您说“避免创建填充纯色的纹理。改用 Blender 的默认颜色/值节点输入。”。我在这里(threejs.org/docs/#manual/en/introduction/How-to-update-things)读到,运行时纹理存在的变化将导致着色器程序重建。对于我将以编程方式(在运行时)添加颜色纹理的材料,我从搅拌机中导出具有 2x2 白色纹理的网格。使用颜色节点会更好吗? 对于 UV:是的,它们将是单独的 GPU 顶点。但它们是同一个绘制调用的一部分(同一个网格图元 + 材质),所以通常没什么大不了的。当顶点数量在制作太多这些后会爆炸时,有些人会感到惊讶。对于另一个问题,是的,如果您在运行时添加纹理,不妨在其中放置一个 2x2 启动器以避免重新编译着色器。

以上是关于Three.js 加载已经三角剖分的网格是不是比使用四边形的网格更高效?的主要内容,如果未能解决你的问题,请参考以下文章

检查点是不是位于球的边界/检查 Delaunay 三角剖分的唯一性

如何在 STL 加载的 BufferGeometry 中平滑网格三角形

Three.js - 大型网格的 BinaryLoader 与 BufferGeometry?

Three.js - 变形几何和细化三角形网格

three.js(13)-三角形面

1039. 多边形三角剖分的最低得分