【问题标题】:Optimizing Three.js for asingle large model针对单个大模型优化 Three.js
【发布时间】:2019-12-17 22:47:32
【问题描述】:

我正在构建一个文件浏览器/3D 模型查看器。我想将各种格式的模型(仅限atm .OBJ)加载到场景中,并使用orbitControls.js 获得合理的帧速率。

我见过的大多数优化策略都集中在处理多个网格而不是一个大网格。 最好的目标是加载巨大的文件(数十万/百万个顶点)而不是让一切崩溃。我知道这很牵强,但我什至不知道从哪里开始优化这个问题,所以我至少可以提高一点帧率。到目前为止,Google 还没有帮助过我

【问题讨论】:

  • 你在使用OBJLoader吗?另外,您使用的是哪个版本的THREE.js
  • 是的,最新版本
  • 对于 webgl1,索引缓冲区的最大可能大小是 65535。因此很少使用单个网格来呈现具有足够细节的模型。重新组合属性缓冲区中的数据可能是可能的。但它如何推动缓冲区大小限制取决于创建模型的算法。
  • 索引缓冲区大小没有限制。如果它被编码为 Short(16 位),则索引值不能超过 65535,因此您不能引用超出此限制的顶点。也就是说,有一个扩展来编码 32 位的索引,这在 webgl1 中几乎 100% 支持。

标签: javascript three.js


【解决方案1】:

OBJLoader 没有做的一件事——这确实有助于提高你的性能——是索引(具有共享顶点/法线对的面)。我从 Blender 导出了一个立方体,得到了 36 个索引(1 个三角形 = 3 个顶点,每个立方体面 2 个三角形 = 6 个顶点,6 个面 = 36 个总顶点)。具有索引的同一个立方体将有 24 个顶点。

索引确实会根据索引的数量增加对象的大小。立方体是一个不好的例子(24 个索引),因为很少有面共享相同的顶点,但对于复杂的网格,节省的成本可能相当高。

我认为解释索引如何工作的所有细节超出了答案的范围,我确信其他资源做得比我做得更好,但这里有一个飞机的小例子:

var planeGeo = new THREE.BufferGeometry();
planeGeo.addAttribute("position", new THREE.BufferAttribute(new Float32Array([
    -10, 10, 0,
    -10, -10, 0,
    10, -10, 0,
    10, 10, 0
]), 3));
planeGeo.addAttribute("normal", new THREE.BufferAttribute(new Float32Array([
    0, 0, 1,
    0, 0, 1,
    0, 0, 1,
    0, 0, 1
]), 3));
planeGeo.setIndex(new THREE.BufferAttribute(new Float32Array([
    // triangle 1
    0, 1, 2,
    // triangle 2
    3, 2, 1
]), 1));

请注意,两个顶点索引被使用了两次,使我们在position 缓冲区中只有一个顶点副本。

但要记住的一件事是索引应该适用于顶点/法线对。顶点和法线没有离散索引,因此如果一个顶点有两条法线,您仍然需要在position 缓冲区中复制顶点值的第二份。

但这对您有什么帮助?好吧,它不直接。我的建议是您要么修改OBJLoader 以创建索引BufferGeometry 对象(parse 方法需要变得更智能以创建正确的索引),或者编写您自己的全新parse 函数。后者实际上对您更有用,因为您可能需要创建新的加载器来处理您希望支持的其他文件格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-15
    • 2018-12-16
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2013-12-02
    • 2016-09-15
    • 1970-01-01
    相关资源
    最近更新 更多