• GLTF格式解析


    前置知识:GLB文件格式解析GLTF文件格式解析 (baidu.com)

    glb格式解析 | 码农家园 (codenong.com)

    3D性能优化 | 说一说glTF文件压缩 - 知乎 (zhihu.com)

    glTF格式详解(目录) - 知乎 (zhihu.com)

    1 GLTF文件

    1. {
    2. "accessors": [
    3. {
    4. "bufferView": 0,
    5. "componentType": 5126,
    6. "count": 3575,
    7. "type": "VEC2",
    8. "max": [
    9. 0.9999003,
    10. -0.0221377648
    11. ],
    12. "min": [
    13. 0.0006585993,
    14. -0.996773958
    15. ]
    16. },
    17. {
    18. "bufferView": 1,
    19. "componentType": 5126,
    20. "count": 3575,
    21. "type": "VEC3",
    22. "max": [
    23. 1.0,
    24. 1.0,
    25. 0.9999782
    26. ],
    27. "min": [
    28. -1.0,
    29. -1.0,
    30. -0.9980823
    31. ]
    32. },
    33. {
    34. "bufferView": 2,
    35. "componentType": 5126,
    36. "count": 3575,
    37. "type": "VEC4",
    38. "max": [
    39. 1.0,
    40. 0.9999976,
    41. 1.0,
    42. 1.0
    43. ],
    44. "min": [
    45. -0.9991289,
    46. -0.999907851,
    47. -1.0,
    48. 1.0
    49. ]
    50. },
    51. {
    52. "bufferView": 3,
    53. "componentType": 5126,
    54. "count": 3575,
    55. "type": "VEC3",
    56. "max": [
    57. 0.009921154,
    58. 0.00977163,
    59. 0.0100762453
    60. ],
    61. "min": [
    62. -0.009921154,
    63. -0.00977163,
    64. -0.0100762453
    65. ]
    66. },
    67. {
    68. "bufferView": 4,
    69. "componentType": 5123,
    70. "count": 18108,
    71. "type": "SCALAR",
    72. "max": [
    73. 3574
    74. ],
    75. "min": [
    76. 0
    77. ]
    78. }
    79. ],
    80. "asset": {
    81. "generator": "glTF Tools for Unity",
    82. "version": "2.0"
    83. },
    84. "bufferViews": [
    85. {
    86. "buffer": 0,
    87. "byteLength": 28600
    88. },
    89. {
    90. "buffer": 0,
    91. "byteOffset": 28600,
    92. "byteLength": 42900
    93. },
    94. {
    95. "buffer": 0,
    96. "byteOffset": 71500,
    97. "byteLength": 57200
    98. },
    99. {
    100. "buffer": 0,
    101. "byteOffset": 128700,
    102. "byteLength": 42900
    103. },
    104. {
    105. "buffer": 0,
    106. "byteOffset": 171600,
    107. "byteLength": 36216
    108. }
    109. ],
    110. "buffers": [
    111. {
    112. "uri": "BoomBox.bin",
    113. "byteLength": 207816
    114. }
    115. ],
    116. "images": [
    117. {
    118. "uri": "BoomBox_baseColor.png"
    119. },
    120. {
    121. "uri": "BoomBox_occlusionRoughnessMetallic.png"
    122. },
    123. {
    124. "uri": "BoomBox_normal.png"
    125. },
    126. {
    127. "uri": "BoomBox_emissive.png"
    128. }
    129. ],
    130. "meshes": [
    131. {
    132. "primitives": [
    133. {
    134. "attributes": {
    135. "TEXCOORD_0": 0,
    136. "NORMAL": 1,
    137. "TANGENT": 2,
    138. "POSITION": 3
    139. },
    140. "indices": 4,
    141. "material": 0
    142. }
    143. ],
    144. "name": "BoomBox"
    145. }
    146. ],
    147. "materials": [
    148. {
    149. "pbrMetallicRoughness": {
    150. "baseColorTexture": {
    151. "index": 0
    152. },
    153. "metallicRoughnessTexture": {
    154. "index": 1
    155. }
    156. },
    157. "normalTexture": {
    158. "index": 2
    159. },
    160. "occlusionTexture": {
    161. "index": 1
    162. },
    163. "emissiveFactor": [
    164. 1.0,
    165. 1.0,
    166. 1.0
    167. ],
    168. "emissiveTexture": {
    169. "index": 3
    170. },
    171. "name": "BoomBox_Mat"
    172. }
    173. ],
    174. "nodes": [
    175. {
    176. "mesh": 0,
    177. "name": "BoomBox"
    178. }
    179. ],
    180. "scene": 0,
    181. "scenes": [
    182. {
    183. "nodes": [
    184. 0
    185. ]
    186. }
    187. ],
    188. "textures": [
    189. {
    190. "source": 0
    191. },
    192. {
    193. "source": 1
    194. },
    195. {
    196. "source": 2
    197. },
    198. {
    199. "source": 3
    200. }
    201. ]
    202. }

    bufferViews":有好几个,为什么每个都设置 "buffer": 0, 这个“buffer”指的啥???

    1. GLTF格式用于描述3D模型和场景的信息。
    2. 在您提供的JSON示例中,
    3. `buffers`,`bufferViews`和`accessors`协同工作以描述3D模型的顶点和其他数据。
    4. ### Buffers
    5. - **Buffers** 是存储实际的二进制数据的地方。在这个例子中,
    6. `"uri": "BoomBox.bin"` 指明了buffer的位置,
    7. `"byteLength": 207816` 描述了buffer的长度。
    8. ```json
    9. "buffers": [
    10. {
    11. "uri": "BoomBox.bin",
    12. "byteLength": 207816
    13. }
    14. ]
    15. ```
    16. ### BufferViews
    17. - **BufferViews** 描述了如何从buffer中查看数据。
    18. 每个`bufferView`有一个`byteOffset`来描述从buffer的哪个位置开始,
    19. 以及`byteLength`来描述view的长度。`"buffer": 0` 指明了该`bufferView`
    20. 是从第一个(也是唯一一个)buffer中查看的。
    21. ```json
    22. "bufferViews": [
    23. {
    24. "buffer": 0,
    25. "byteLength": 28600
    26. },
    27. ...
    28. ]
    29. ```
    30. ### Accessors
    31. - **Accessors** 则进一步描述了如何从`bufferView`中解读数据。
    32. 它会定义component的类型,例如,是否是一个VEC3或者SCALAR,
    33. 以及数据的类型,例如,是否是FLOAT。它还会包含一些有关数据的其他信息,例如min和max值。
    34. ```json
    35. "accessors": [
    36. {
    37. "bufferView": 0,
    38. "componentType": 5126,
    39. "count": 3575,
    40. "type": "VEC2",
    41. ...
    42. },
    43. ...
    44. ]
    45. ```
    46. ### 为什么每个 BufferView 的 `"buffer": 0` ?
    47. 在您的JSON示例中,所有的`bufferViews`都有`"buffer": 0`,
    48. 这是因为所有的`bufferViews`都是从同一个buffer中提取的,
    49. 也就是上述`buffers`数组中的第一个(并且是唯一的)buffer。
    50. 如果您的GLTF文件中有多个buffer,那么您将会看到不同的`bufferViews`
    51. 关联到不同的buffer。例如,如果有一个`bufferView`从第二个buffer中
    52. 提取数据,那么它将会有`"buffer": 1`。

    "accessors": [ { "bufferView": 0, "componentType": 5126, "count": 3575, "type": "VEC2", ... }, ... ]

    这accessors中的每一个bufferView可以重复吗,比如accessors三个孩子,bufferView分别为0,1,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":[{
    2. "primitives":[{"attributes":{"NORMAL":1,"POSITION":2},"indices":0,"mode":4,"material":0}],"name":"Mesh"}],
    3. "accessors":[
    4. {"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"}]
    5. ,"materials":[{"pbrMetallicRoughness":{"baseColorFactor":[0.800000011920929,0.0,0.0,1.0],"metallicFactor":0.0},"name":"Red"}],
    6. "bufferViews":[
    7. {"buffer":0,"byteOffset":576,"byteLength":72,"target":34963},
    8. {"buffer":0,"byteOffset":0,"byteLength":576,"byteStride":12,"target":34962}],
    9. "buffers":[{"byteLength":648}]}
    1. 是的,`accessors`中的`bufferView`可以重复。每个`accessor`定义了
    2. 如何解读存储在`bufferView`中的数据。不同的`accessor`可以使用相同
    3. 的`bufferView`,但可能会有不同的`byteOffset`、`componentType`、
    4. `count`或`type`,以便以不同的方式解读相同的数据,或解读该`bufferView`
    5. 中的不同部分数据。
    6. 举个例子,假设我们有两个`accessor`,它们都指向`bufferView` 1,但
    7. 一个是解读VEC3类型数据,另一个是解读SCALAR类型数据。那么,这两个
    8. `accessor`将会从相同的`bufferView`中提取不同类型和格式的数据。
    9. ```json
    10. "accessors": [
    11. {
    12. "bufferView": 1,
    13. "componentType": 5126,
    14. "count": 1000,
    15. "type": "VEC3"
    16. },
    17. {
    18. "bufferView": 1,
    19. "componentType": 5123,
    20. "count": 2000,
    21. "type": "SCALAR"
    22. }
    23. ]
    24. ```
    25. 在这个例子中,即便两个`accessor`都引用了`bufferView` 1,但由于
    26. 它们有不同的`type`和`componentType`,它们将会以不同的方式解读
    27. `bufferView`中的数据。

    2 GLB文件并进行了Draco压缩

    1. glTF T ? JSON{
    2. "asset": {
    3. "version": "2.0",
    4. "generator": "draco_decoder"
    5. },
    6. "scenes": [
    7. {
    8. "nodes": [
    9. 0
    10. ]
    11. }
    12. ],
    13. "scene": 0,
    14. "nodes": [
    15. {
    16. "children": [
    17. 1
    18. ],
    19. "matrix": [
    20. 1,
    21. 0,
    22. 0,
    23. 0,
    24. 0,
    25. 0,
    26. -1,
    27. 0,
    28. 0,
    29. 1,
    30. 0,
    31. 0,
    32. 0,
    33. 0,
    34. 0,
    35. 1
    36. ]
    37. },
    38. {
    39. "mesh": 0
    40. }
    41. ],
    42. "meshes": [
    43. {
    44. "primitives": [
    45. {
    46. "attributes": {
    47. "NORMAL": 2,
    48. "POSITION": 1
    49. },
    50. "indices": 0,
    51. "mode": 4,
    52. "material": 0,
    53. "extensions": {
    54. "KHR_draco_mesh_compression": {
    55. "bufferView": 0,
    56. "attributes": {
    57. "NORMAL": 0,
    58. "POSITION": 1
    59. }
    60. }
    61. }
    62. }
    63. ]
    64. }
    65. ],
    66. "materials": [
    67. {
    68. "pbrMetallicRoughness": {
    69. "baseColorFactor": [
    70. 0.800000011920929,
    71. 0,
    72. 0,
    73. 1
    74. ],
    75. "metallicFactor": 0,
    76. "roughnessFactor": 1
    77. },
    78. "emissiveFactor": [
    79. 0,
    80. 0,
    81. 0
    82. ],
    83. "alphaMode": "OPAQUE"
    84. }
    85. ],
    86. "accessors": [
    87. {
    88. "componentType": 5121,
    89. "count": 36,
    90. "normalized": false,
    91. "max": [
    92. 23
    93. ],
    94. "min": [
    95. 0
    96. ],
    97. "type": "SCALAR"
    98. },
    99. {
    100. "componentType": 5126,
    101. "count": 24,
    102. "normalized": false,
    103. "max": [
    104. 0.5,
    105. 0.5,
    106. 0.5
    107. ],
    108. "min": [
    109. -0.5,
    110. -0.5,
    111. -0.5
    112. ],
    113. "type": "VEC3"
    114. },
    115. {
    116. "componentType": 5126,
    117. "count": 24,
    118. "normalized": false,
    119. "max": [
    120. 1,
    121. 1,
    122. 1
    123. ],
    124. "min": [
    125. -1,
    126. -1,
    127. -1
    128. ],
    129. "type": "VEC3"
    130. }
    131. ],
    132. "bufferViews": [
    133. {
    134. "buffer": 0,
    135. "byteOffset": 0,
    136. "byteLength": 152
    137. }
    138. ],
    139. "buffers": [
    140. {
    141. "byteLength": 152
    142. }
    143. ],
    144. "extensionsRequired": [
    145. "KHR_draco_mesh_compression"
    146. ],
    147. "extensionsUsed": [
    148. "KHR_draco_mesh_compression"
    149. ]
    150. }
    151. ? BIN DRACO
    152. ??鱑?喊﹤ ???鏌?I)?皷 ?  ? ? ? €?
    1. 这段 JSON 是 glTF(GL Transmission Format)格式的,一个用于
    2. 3D 场景和模型的传输格式。这个例子中使用了 Draco 压缩,这是一
    3. 种几何图形压缩方法,可以大幅减小 3D 模型的文件大小。
    4. 以下是该 JSON 文件的组织结构:
    5. 1. **asset**
    6. - 描述了 glTF 资源的信息,比如版本和生成器。
    7. 2. **scenes**
    8. - 定义了 3D 场景的列表,其中包含了场景所包含的节点(nodes)。
    9. 3. **scene**
    10. - 表示当前要展示的场景。
    11. 4. **nodes**
    12. - 定义了场景中的节点列表,其中每个节点可能包含子节点、网格、变换矩阵等。
    13. 5. **meshes**
    14. - 定义了网格的列表。每个网格都包含了一组 primitive,每个 primitive
    15. 都有自己的 attributes,如位置、法线等。
    16. 6. **materials**
    17. - 定义了场景中使用的材料的属性。
    18. 7. **accessors**
    19. - 定义了如何从 bufferView 中访问数据,包含了类型、数量等信息。
    20. 8. **bufferViews**
    21. - 定义了如何在 buffer 中访问原始二进制数据。
    22. 9. **buffers**
    23. - 存储了原始二进制数据的长度信息。
    24. 10. **extensionsRequired 和 extensionsUsed**
    25. - 定义了此 glTF 模型所需和所用的扩展,本例中使用了 Draco 压缩的扩展。
    26. ### Draco 压缩
    27. 在这个例子中,`"KHR_draco_mesh_compression"` 扩展被使用,表示模型数据经
    28. 过了 Draco 压缩。压缩后的数据存储在 `buffer` 中。Draco 压缩的具体信息是
    29. 在每个 `primitive` 的 `extensions` 字段中定义的:
    30. ```json
    31. "extensions": {
    32. "KHR_draco_mesh_compression": {
    33. "bufferView": 0,
    34. "attributes": {
    35. "NORMAL": 0,
    36. "POSITION": 1
    37. }
    38. }
    39. }
    40. ```
    41. 这里的 `bufferView` 指向包含压缩数据的 `bufferView`,而 `attributes` 定义
    42. 了属性类型和对应的索引,这些索引对应于 Draco 压缩数据中的属性。
    43. 总而言之,这个 JSON 文件定义了一个 glTF 场景,其中包含了节点、网格、材料、访
    44. 问器、缓冲视图和缓冲器,以及 Draco 压缩的扩展,以减小 3D 模型的文件大小。 若
    45. 要渲染这个 3D 模型,需要按照定义在访问器和缓冲视图中的信息,从缓冲中获取原始
    46. 数据,然后解压 Draco 压缩的数据,最后应用材料并将其放入场景中。

    indices是怎么来的,我看其他glb文件有的是1,有的是2???

    1. 在 glTF 结构中,`primitives`字段定义了如何将顶点属性组合成几何图元。
    2. 每个`primitive`都包含一个`attributes`对象,`attributes`对象定义了
    3. 一组`accessor`,这些`accessor`引用了包含实际几何数据的缓冲区视图
    4. (`bufferView`)。`indices`字段则是一个指向`accessor`的索引,这个
    5. `accessor`包含了组成这些几何图元的索引。
    6. - `"indices": 0`表示用来组成几何图元的索引存储在`accessors`数组的第一个元素中。
    7. - `"indices": 1`表示索引存储在`accessors`数组的第二个元素中。
    8. - `"indices": 2`表示索引存储在`accessors`数组的第三个元素中。
    9. 以此类推。这个`indices`引用的`accessor`定义了如何从`attributes`指定的
    10. 顶点属性中索引值,来组成三角形或其他几何图元。
    11. 例如,如果您有以下几何结构:
    12. ```
    13. "accessors": [
    14. { ... }, // 0: indices
    15. { ... }, // 1: POSITION
    16. { ... } // 2: NORMAL
    17. ],
    18. "primitives": [
    19. {
    20. "attributes": {
    21. "POSITION": 1,
    22. "NORMAL": 2
    23. },
    24. "indices": 0,
    25. }
    26. ]
    27. ```
    28. 在这个例子中,`indices`是`0`,意味着`accessors`数组的第一个元素包含了
    29. 组成几何图元的索引。而`POSITION`和`NORMAL`属性分别由`accessors`数组的
    30. 第二个和第三个元素提供。
    31. 所以,如果您在不同的glTF或glb文件中看到不同的`indices`值,这仅仅是因为
    32. 这些索引存储在`accessors`数组中不同的位置。这并不会影响最终模型的几何
    33. 结构,因为`indices`和`attributes`的组合提供了完整的几何定义。

  • 相关阅读:
    『现学现忘』Docker相关概念 — 2、云计算的服务模式
    Airtest框架和Poco框架常见问题
    网络安全运维流量攻击分析需要掌握的核心能力有什么
    XML 发票解析
    2023年数维杯数学建模C题宫内节育器的生产求解全过程文档及程序
    备战2023秋招,应届生应做好哪些准备
    Axios笔记
    迁移学习 - 微调
    常用电路符号
    2023-2028年中国高纯度巯基乙酸市场需求预测与投资方向研究报告
  • 原文地址:https://blog.csdn.net/qq_59068750/article/details/133341447