前置知识:GLB文件格式解析GLTF文件格式解析 (baidu.com)
3D性能优化 | 说一说glTF文件压缩 - 知乎 (zhihu.com)
- {
- "accessors": [
- {
- "bufferView": 0,
- "componentType": 5126,
- "count": 3575,
- "type": "VEC2",
- "max": [
- 0.9999003,
- -0.0221377648
- ],
- "min": [
- 0.0006585993,
- -0.996773958
- ]
- },
- {
- "bufferView": 1,
- "componentType": 5126,
- "count": 3575,
- "type": "VEC3",
- "max": [
- 1.0,
- 1.0,
- 0.9999782
- ],
- "min": [
- -1.0,
- -1.0,
- -0.9980823
- ]
- },
- {
- "bufferView": 2,
- "componentType": 5126,
- "count": 3575,
- "type": "VEC4",
- "max": [
- 1.0,
- 0.9999976,
- 1.0,
- 1.0
- ],
- "min": [
- -0.9991289,
- -0.999907851,
- -1.0,
- 1.0
- ]
- },
- {
- "bufferView": 3,
- "componentType": 5126,
- "count": 3575,
- "type": "VEC3",
- "max": [
- 0.009921154,
- 0.00977163,
- 0.0100762453
- ],
- "min": [
- -0.009921154,
- -0.00977163,
- -0.0100762453
- ]
- },
- {
- "bufferView": 4,
- "componentType": 5123,
- "count": 18108,
- "type": "SCALAR",
- "max": [
- 3574
- ],
- "min": [
- 0
- ]
- }
- ],
- "asset": {
- "generator": "glTF Tools for Unity",
- "version": "2.0"
- },
- "bufferViews": [
- {
- "buffer": 0,
- "byteLength": 28600
- },
- {
- "buffer": 0,
- "byteOffset": 28600,
- "byteLength": 42900
- },
- {
- "buffer": 0,
- "byteOffset": 71500,
- "byteLength": 57200
- },
- {
- "buffer": 0,
- "byteOffset": 128700,
- "byteLength": 42900
- },
- {
- "buffer": 0,
- "byteOffset": 171600,
- "byteLength": 36216
- }
- ],
- "buffers": [
- {
- "uri": "BoomBox.bin",
- "byteLength": 207816
- }
- ],
- "images": [
- {
- "uri": "BoomBox_baseColor.png"
- },
- {
- "uri": "BoomBox_occlusionRoughnessMetallic.png"
- },
- {
- "uri": "BoomBox_normal.png"
- },
- {
- "uri": "BoomBox_emissive.png"
- }
- ],
- "meshes": [
- {
- "primitives": [
- {
- "attributes": {
- "TEXCOORD_0": 0,
- "NORMAL": 1,
- "TANGENT": 2,
- "POSITION": 3
- },
- "indices": 4,
- "material": 0
- }
- ],
- "name": "BoomBox"
- }
- ],
- "materials": [
- {
- "pbrMetallicRoughness": {
- "baseColorTexture": {
- "index": 0
- },
- "metallicRoughnessTexture": {
- "index": 1
- }
- },
- "normalTexture": {
- "index": 2
- },
- "occlusionTexture": {
- "index": 1
- },
- "emissiveFactor": [
- 1.0,
- 1.0,
- 1.0
- ],
- "emissiveTexture": {
- "index": 3
- },
- "name": "BoomBox_Mat"
- }
- ],
- "nodes": [
- {
- "mesh": 0,
- "name": "BoomBox"
- }
- ],
- "scene": 0,
- "scenes": [
- {
- "nodes": [
- 0
- ]
- }
- ],
- "textures": [
- {
- "source": 0
- },
- {
- "source": 1
- },
- {
- "source": 2
- },
- {
- "source": 3
- }
- ]
- }
bufferViews":有好几个,为什么每个都设置 "buffer": 0, 这个“buffer”指的啥???
- GLTF格式用于描述3D模型和场景的信息。
- 在您提供的JSON示例中,
- `buffers`,`bufferViews`和`accessors`协同工作以描述3D模型的顶点和其他数据。
-
- ### Buffers
- - **Buffers** 是存储实际的二进制数据的地方。在这个例子中,
- `"uri": "BoomBox.bin"` 指明了buffer的位置,
- `"byteLength": 207816` 描述了buffer的长度。
-
- ```json
- "buffers": [
- {
- "uri": "BoomBox.bin",
- "byteLength": 207816
- }
- ]
- ```
-
- ### BufferViews
- - **BufferViews** 描述了如何从buffer中查看数据。
- 每个`bufferView`有一个`byteOffset`来描述从buffer的哪个位置开始,
- 以及`byteLength`来描述view的长度。`"buffer": 0` 指明了该`bufferView`
- 是从第一个(也是唯一一个)buffer中查看的。
-
- ```json
- "bufferViews": [
- {
- "buffer": 0,
- "byteLength": 28600
- },
- ...
- ]
- ```
-
- ### Accessors
- - **Accessors** 则进一步描述了如何从`bufferView`中解读数据。
- 它会定义component的类型,例如,是否是一个VEC3或者SCALAR,
- 以及数据的类型,例如,是否是FLOAT。它还会包含一些有关数据的其他信息,例如min和max值。
-
- ```json
- "accessors": [
- {
- "bufferView": 0,
- "componentType": 5126,
- "count": 3575,
- "type": "VEC2",
- ...
- },
- ...
- ]
- ```
-
- ### 为什么每个 BufferView 的 `"buffer": 0` ?
- 在您的JSON示例中,所有的`bufferViews`都有`"buffer": 0`,
- 这是因为所有的`bufferViews`都是从同一个buffer中提取的,
- 也就是上述`buffers`数组中的第一个(并且是唯一的)buffer。
-
- 如果您的GLTF文件中有多个buffer,那么您将会看到不同的`bufferViews`
- 关联到不同的buffer。例如,如果有一个`bufferView`从第二个buffer中
- 提取数据,那么它将会有`"buffer": 1`。
"accessors": [ { "bufferView": 0, "componentType": 5126, "count": 3575, "type": "VEC2", ... }, ... ]
这accessors中的每一个bufferView可以重复吗,比如accessors三个孩子,bufferView分别为0,1,1???
比如这种文件
- {"asset":{"generator":"COLLADA2GLTF","version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"children":[1],"matrix":[1.0,0.0,0.0,0.0,0.0,0.0,-1.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,1.0]},{"mesh":0}],"meshes":[{
-
- "primitives":[{"attributes":{"NORMAL":1,"POSITION":2},"indices":0,"mode":4,"material":0}],"name":"Mesh"}],
-
- "accessors":[
-
- {"bufferView":0,"byteOffset":0,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":24,"max":[1.0,1.0,1.0],"min":[-1.0,-1.0,-1.0],"type":"VEC3"},{"bufferView":1,"byteOffset":288,"componentType":5126,"count":24,"max":[0.5,0.5,0.5],"min":[-0.5,-0.5,-0.5],"type":"VEC3"}]
-
- ,"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.800000011920929,0.0,0.0,1.0],"metallicFactor":0.0},"name":"Red"}],
-
- "bufferViews":[
- {"buffer":0,"byteOffset":576,"byteLength":72,"target":34963},
- {"buffer":0,"byteOffset":0,"byteLength":576,"byteStride":12,"target":34962}],
- "buffers":[{"byteLength":648}]}
- 是的,`accessors`中的`bufferView`可以重复。每个`accessor`定义了
- 如何解读存储在`bufferView`中的数据。不同的`accessor`可以使用相同
- 的`bufferView`,但可能会有不同的`byteOffset`、`componentType`、
- `count`或`type`,以便以不同的方式解读相同的数据,或解读该`bufferView`
- 中的不同部分数据。
-
- 举个例子,假设我们有两个`accessor`,它们都指向`bufferView` 1,但
- 一个是解读VEC3类型数据,另一个是解读SCALAR类型数据。那么,这两个
- `accessor`将会从相同的`bufferView`中提取不同类型和格式的数据。
-
- ```json
- "accessors": [
- {
- "bufferView": 1,
- "componentType": 5126,
- "count": 1000,
- "type": "VEC3"
- },
- {
- "bufferView": 1,
- "componentType": 5123,
- "count": 2000,
- "type": "SCALAR"
- }
- ]
- ```
-
- 在这个例子中,即便两个`accessor`都引用了`bufferView` 1,但由于
- 它们有不同的`type`和`componentType`,它们将会以不同的方式解读
- `bufferView`中的数据。
- glTF T ? JSON{
- "asset": {
- "version": "2.0",
- "generator": "draco_decoder"
- },
- "scenes": [
- {
- "nodes": [
- 0
- ]
- }
- ],
- "scene": 0,
- "nodes": [
- {
- "children": [
- 1
- ],
- "matrix": [
- 1,
- 0,
- 0,
- 0,
- 0,
- 0,
- -1,
- 0,
- 0,
- 1,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1
- ]
- },
- {
- "mesh": 0
- }
- ],
- "meshes": [
- {
- "primitives": [
- {
- "attributes": {
- "NORMAL": 2,
- "POSITION": 1
- },
- "indices": 0,
- "mode": 4,
- "material": 0,
- "extensions": {
- "KHR_draco_mesh_compression": {
- "bufferView": 0,
- "attributes": {
- "NORMAL": 0,
- "POSITION": 1
- }
- }
- }
- }
- ]
- }
- ],
- "materials": [
- {
- "pbrMetallicRoughness": {
- "baseColorFactor": [
- 0.800000011920929,
- 0,
- 0,
- 1
- ],
- "metallicFactor": 0,
- "roughnessFactor": 1
- },
- "emissiveFactor": [
- 0,
- 0,
- 0
- ],
- "alphaMode": "OPAQUE"
- }
- ],
- "accessors": [
- {
- "componentType": 5121,
- "count": 36,
- "normalized": false,
- "max": [
- 23
- ],
- "min": [
- 0
- ],
- "type": "SCALAR"
- },
- {
- "componentType": 5126,
- "count": 24,
- "normalized": false,
- "max": [
- 0.5,
- 0.5,
- 0.5
- ],
- "min": [
- -0.5,
- -0.5,
- -0.5
- ],
- "type": "VEC3"
- },
- {
- "componentType": 5126,
- "count": 24,
- "normalized": false,
- "max": [
- 1,
- 1,
- 1
- ],
- "min": [
- -1,
- -1,
- -1
- ],
- "type": "VEC3"
- }
- ],
- "bufferViews": [
- {
- "buffer": 0,
- "byteOffset": 0,
- "byteLength": 152
- }
- ],
- "buffers": [
- {
- "byteLength": 152
- }
- ],
- "extensionsRequired": [
- "KHR_draco_mesh_compression"
- ],
- "extensionsUsed": [
- "KHR_draco_mesh_compression"
- ]
- }
- ? BIN DRACO
-
-
-
- ??鱑?喊﹤ ???鏌?I)?皷 ? ? ? ? €?
- 这段 JSON 是 glTF(GL Transmission Format)格式的,一个用于
- 3D 场景和模型的传输格式。这个例子中使用了 Draco 压缩,这是一
- 种几何图形压缩方法,可以大幅减小 3D 模型的文件大小。
-
- 以下是该 JSON 文件的组织结构:
-
- 1. **asset**
- - 描述了 glTF 资源的信息,比如版本和生成器。
-
- 2. **scenes**
- - 定义了 3D 场景的列表,其中包含了场景所包含的节点(nodes)。
-
- 3. **scene**
- - 表示当前要展示的场景。
-
- 4. **nodes**
- - 定义了场景中的节点列表,其中每个节点可能包含子节点、网格、变换矩阵等。
-
- 5. **meshes**
- - 定义了网格的列表。每个网格都包含了一组 primitive,每个 primitive
- 都有自己的 attributes,如位置、法线等。
-
- 6. **materials**
- - 定义了场景中使用的材料的属性。
-
- 7. **accessors**
- - 定义了如何从 bufferView 中访问数据,包含了类型、数量等信息。
-
- 8. **bufferViews**
- - 定义了如何在 buffer 中访问原始二进制数据。
-
- 9. **buffers**
- - 存储了原始二进制数据的长度信息。
-
- 10. **extensionsRequired 和 extensionsUsed**
- - 定义了此 glTF 模型所需和所用的扩展,本例中使用了 Draco 压缩的扩展。
-
- ### Draco 压缩
-
- 在这个例子中,`"KHR_draco_mesh_compression"` 扩展被使用,表示模型数据经
- 过了 Draco 压缩。压缩后的数据存储在 `buffer` 中。Draco 压缩的具体信息是
- 在每个 `primitive` 的 `extensions` 字段中定义的:
-
- ```json
- "extensions": {
- "KHR_draco_mesh_compression": {
- "bufferView": 0,
- "attributes": {
- "NORMAL": 0,
- "POSITION": 1
- }
- }
- }
- ```
-
- 这里的 `bufferView` 指向包含压缩数据的 `bufferView`,而 `attributes` 定义
- 了属性类型和对应的索引,这些索引对应于 Draco 压缩数据中的属性。
-
- 总而言之,这个 JSON 文件定义了一个 glTF 场景,其中包含了节点、网格、材料、访
- 问器、缓冲视图和缓冲器,以及 Draco 压缩的扩展,以减小 3D 模型的文件大小。 若
- 要渲染这个 3D 模型,需要按照定义在访问器和缓冲视图中的信息,从缓冲中获取原始
- 数据,然后解压 Draco 压缩的数据,最后应用材料并将其放入场景中。
indices是怎么来的,我看其他glb文件有的是1,有的是2???
- 在 glTF 结构中,`primitives`字段定义了如何将顶点属性组合成几何图元。
- 每个`primitive`都包含一个`attributes`对象,`attributes`对象定义了
- 一组`accessor`,这些`accessor`引用了包含实际几何数据的缓冲区视图
- (`bufferView`)。`indices`字段则是一个指向`accessor`的索引,这个
- `accessor`包含了组成这些几何图元的索引。
-
- - `"indices": 0`表示用来组成几何图元的索引存储在`accessors`数组的第一个元素中。
- - `"indices": 1`表示索引存储在`accessors`数组的第二个元素中。
- - `"indices": 2`表示索引存储在`accessors`数组的第三个元素中。
-
- 以此类推。这个`indices`引用的`accessor`定义了如何从`attributes`指定的
- 顶点属性中索引值,来组成三角形或其他几何图元。
-
- 例如,如果您有以下几何结构:
- ```
- "accessors": [
- { ... }, // 0: indices
- { ... }, // 1: POSITION
- { ... } // 2: NORMAL
- ],
- "primitives": [
- {
- "attributes": {
- "POSITION": 1,
- "NORMAL": 2
- },
- "indices": 0,
- }
- ]
- ```
-
- 在这个例子中,`indices`是`0`,意味着`accessors`数组的第一个元素包含了
- 组成几何图元的索引。而`POSITION`和`NORMAL`属性分别由`accessors`数组的
- 第二个和第三个元素提供。
-
- 所以,如果您在不同的glTF或glb文件中看到不同的`indices`值,这仅仅是因为
- 这些索引存储在`accessors`数组中不同的位置。这并不会影响最终模型的几何
- 结构,因为`indices`和`attributes`的组合提供了完整的几何定义。