网格数据应如何分布在 glTF 文件中的访问器、bufferViews、缓冲区之间?

问题描述 投票:0回答:1

glTF 格式中, 网格对象位置经历三个间接级别: 网格 -> 访问器 -> bufferView -> 缓冲区。

网格数据应如何在访问器之间分布, glTF 文件中的 bufferView 和缓冲区?有关系吗?

例如假设我有两个网格,每个网格都有一个 POSITION 属性。 看来我基本上有四种布局选择 glTF 文件中的位置数据:

===============================================================
(A) one big shared accessor,bufferView,buffer for all positions
mesh 0 -+
        +-> accessor 0 ---> bufferView 0 ---> buffer 0
mesh 1 -+
===============================================================
(B) accessor per mesh, one big shared bufferView,buffer
mesh 0 ---> accessor 0 -+
                        +-> bufferView 0 ---> buffer 0
mesh 1 ---> accessor 1 -+
===============================================================
(C) accessor,bufferView per mesh, one big shared buffer
mesh 0 ---> accessor 0 ---> bufferView 0 -+
                                          +-> buffer 0
mesh 1 ---> accessor 1 ---> bufferView 1 -+
===============================================================
(D) accessor,bufferView,buffer per mesh
mesh 0 ---> accessor 0 ---> bufferView 0 ---> buffer 0
mesh 1 ---> accessor 1 ---> bufferView 1 ---> buffer 1
===============================================================

在上述四种布局选择中,(A) 生成最简单、最紧凑的 glTF 文件 (特别是如果两个网格共享一些顶点位置)。 所以我不确定为什么我会使用 (B)、(C) 或 (D) 中的任何一个。

我问的原因是我目前正在使用 (A) 创建 glTF 文件 (每个文件包含数千个网格), 但我发现当我 将文件加载到 Three.js 中并使用它。例如:

  • 网格边界框未正确计算 Box3.setFromObject (而不是仅在这些顶点周围生成紧密的边界框 由给定网格引用, 它会在访问器中的所有位置周围生成一个边界框...或者可能是 bufferView)
  • 我想也许我的单个大缓冲区(或 bufferView?或访问器? 不确定哪个)在内存和/或 GPU 内存中被重复多次 (每个引用它的网格一次?可能有数千个), 这似乎严重限制了我可以看到的场景大小。

所以我认为必须有一个假设(由 Threejs 和/或其他消费者 glTF 文件),我正在使用 (B)、(C) 或 (D) 代替? 但我不知道假设的是什么,或者一般来说我应该使用哪种布局。

three.js gltf
1个回答
0
投票

我倾向于用这些术语来思考缓冲区和缓冲区视图:

  • 缓冲区是通过网络存储和传输的单位。
  • 缓冲区视图是上传到GPU、动画系统等的单位。

在大多数情况下,您应该只需要一个缓冲区任何细分通常都是为了特定于应用程序的目的,例如对来自不同网格或动画的数据进行分区,以便可以在不同时间通过网络下载。

理论上,缓冲区视图越少越好。在实践中,大多数 3D 引擎都有限制,会影响最佳选择。 正如您所描述的, Three.js 在跨多个 THREE.BufferGeometry 实例共享顶点数据方面做得不太好。除了边界框问题(可能可以解决!)之外,它目前还会“将每个 BufferGeometry 分别上传到 GPU”,这会重复数据,并且解决起来更加复杂。因此,特别是对于 Three.js,理想的布局可能是每个网格图元一个缓冲区视图,每个网格图元内的顶点属性在该单个缓冲区视图中交错。 因此,虽然引擎的目标是至少支持所有内容,但它们可能针对特定布局进行了“优化”。在实践中,为目标引擎预处理 glTF 文件会很有帮助,以缩短加载时间。 gltfpack 或 glTF Transform 是可以在这里使用的流行工具。

示例: npm install --global @gltf-transform/cli # aims for one interleaved buffer view per mesh primitive gltf-transform cp in.glb out.glb --vertex-layout interleaved # aims for one buffer view per vertex attribute gltf-transform cp in.glb out.glb --vertex-layout separate

特定情况(例如压缩或在多个几何图形中共享单个顶点属性)确实使情况变得复杂,并且需要编码器做出更多决策。

三.js r164


© www.soinside.com 2019 - 2024. All rights reserved.