glb数据格式
glb 文件格式只包含一个glb 文件,文件按照二进制存储,占空间小
浏览
浏览glb工具的很多,ccs,3D查看器等都可以,不安装软件的话用下面网页加载就可以,免费
glTF Viewer (donmccurdy.com)
glbxz.com 模型网
GLTF 编辑器 -NSDT

参考资料
完整的介绍文档可以参考以下几个
GLB文件 (sarkuya.com)
glTF 2.0 - Blender 4.2 手册
GLB (fileformat.com)
glTF Tutorial | glTF-Tutorials (khronos.org)
文件格式
开始正文介绍,二进制的glb文件打开后结构如下:

整体结构的包含一个文件头,一个Json的chunk,一个bin的chunk存储图像,动画,纹理等
header
头部数据长度12个字节
#读取12个字节,按照小端,转换为无符号整数
header = f.read(12)
magic, version, length = struct.unpack('<III', header)
| 名称 | 说明 | 数值 | 解释 | 
|---|---|---|---|
| magic | 魔术字 | 0x46546C67 | 对应ascII码glTF | 
| version | 版本 | 2 | GITF的版本 | 
| length | 长度 | 746776 | 包括文件头的文件总长度 | 
chunk0
一个glb文件可以存在多个chunk,但是chunk0是必须的,其格式是固定的
# 读取8个字节,存储字节总长度和chunk类型,按照字节长度截取数据存储为chunkdata
chunk_header = f.read(8)
chunk_length, chunk_type = struct.unpack('<II', chunk_header)
if chunk_type != 0x4E4F534A:
    raise ValueError("Expected JSON chunk.")
json_chunk = f.read(chunk_length)
gltf_data = json.loads(json_chunk.decode('utf-8'))
| 名称 | 说明 | 数值 | 
|---|---|---|
| chunkLength | 字节总长度 | 7420(测试值) | 
| chunkType | 数据类型 | 0x4E4F534A,对应ascII是JSON | 
| chunkData | 数据 | JSON数据 | 
#使用该指令可以将无符号整数转ascII,对应值是JSON
chunk_type.to_bytes(4, byteorder='little').decode('ascii')
chunkData

已知数据格式为JSON,所以将数据按照utf-8编码转换为对应的数据JSON数据,并打印出来
gltf_data = json.loads(json_chunk.decode('utf-8'))
print(json.dumps(gltf_data, indent=4))
对应打印值对应如下:

接下来对JSON结构进行解释,其加载顺序对应是scenes、nodes、meshes、accessors、bufferViews、buffers、materials、textures、images。其中每个mesh包括一个bufferViews和一个materials。每一层的递进都有数组下标来确定,结构存储在buffer中,纹理存储在image中
| 名称 | 说明 | 包含 | 声明 | 
|---|---|---|---|
| scenes | 场景 | nodes | |
| nodes | 节点 | mesh、translation、chidren,camera、skin | |
| meshes | 网格 | attributes、indices、material | 网格所需数据 | 
| accessors | 访问器 | bufferView、componentType、count、type | 缓冲器索引,数据类型,大小 | 
| bufferViews | 缓冲器 | buffer、byteOffset、byteLength、target | buffer对应得位置 | 
| buffers | 缓冲数据 | byteLength,uri、name | buffer的字节长度 | 
| materials | 材质 | baseColorTexture、metallicFactor、roughnessFactor、extensions | 材质参数,以及纹理索引 | 
| textures | 纹理 | source,sampler | 照片索引和采样器索引 | 
| images | 照片 | name、uri、bufferView、mimeType | 纹理文件索引,文件格式 | 
| samplers | 采样器 | magFilter、minFilter | 放大缩小时滤波器 | 
scenes
对应模型得场景,一般模型一个场景,即默认场景;
每个场景包含一个node字段,指定了sence的根节点,
下图包含一个scene对象,该对应指定了一个索引为2的node节点

nodes
节点,所有的节点构成scene,可以包含网格mesh、变换translation,子节点children,相机camera、纹理skin等
| 名称 | 说明 | 
|---|---|
| mesh | 网格信息 存放网格索引 | 
| children | 子节点,该节点包含的子节点 | 
| translation | 平移信息 | 
| rotation | 旋转信息,四元数 | 
| scale | 缩放信息 | 
| name | 节点名 | 
| matrix | 局部变换矩阵,16浮点矩阵数组,平移,旋转,尺度 | 
下图node包含
一个mesh,其索引值为0
一个子节点children,索引为0,并且包含了其变化参数translation,对应节点名称为rtc
一个子节点children,索引为1,并且包含了对应姿态matrix,对应节点名称为rootNode
所以根据使用得关系是rootnode给了rtc一个属性matrix,然后rtc给了mesh一个属性translation,等于mesh继承了器各个属性


meshes
meshes网格,包含构建一个网格所需要的数据"primitives"数组,,其包含的属性值有
- attributes:包含"NORMAL"、“POSITION”、“TEXCOORD_0”、“TANGENT”、“JOINTS_0”、“WEIGHTS_0”等数据的索引
- indices:存储属性accessors的数组索引
- material:存储属性material材质的数组索引
| 名称 | 说明,对应于accessors索引 | 
|---|---|
| NORMAL | 顶点的法线 | 
| POSITION | 顶点的位置 | 
| TEXCOORD_0 | 顶点的uv坐标 | 
| TANGENT | 顶点的切线 | 
| JOINTS_0 | 顶点受骨骼节点的约束 | 
| WEIGHTS_0 | 顶点受骨骼节点约束的权重 | 
该mesh包含7个网格,其中第一个网格包含顶点位置索引0,对应uv坐标索引1;对应accessors索引2,材质索引0

accessors
accessors访问器:是访问buffer的中间件,是bufferView和mesh之间的桥梁,表明bufferView的索引
| 名称 | 说明 | 
|---|---|
| bufferView | 在bufferViews中的索引 | 
| componentType | 数据类型 5120:byte; 5121:ubyte;5122:short; 5123:ushort;5124:int; 5125:uint; 5126:float; 5130:double | 
| count | 数据个数 | 
| type | 数据类型, ‘SCALAR’: 1,标量 ‘VEC2’: 2,‘VEC3’: 3,‘VEC4’: 4, 对应n维向量 ‘MAT2’: 4,‘MAT3’: 9‘MAT4’: 16, //n2维矩阵 | 
| max | 所有的数据中最大值 | 
| min | 所有的数据中最小值 | 
该accessors 访问器包含多个中间件,其中
 第一个中间件,对应bufferviews索引1,float类型,共9185个三维向量数据,最大最小值对应如下
第二个中间件,对应bufferviews索引2,float类型,共9185个二维向量数据,最大最小值对应如下
第三个中间件,对应bufferviews索引3,ushort类型,共18297个标量数据,最大最小值对应如下

bufferViews
bufferViews表明数据在buffer中的具体位置
| 名称 | 说明 | 
|---|---|
| buffer | buffer数据的索引 | 
| byteOffset | buffer的字节偏移量 | 
| byteLength | buffer的字节长度 | 
| target | 缓冲类型, 顶点属性 vertex attributes,34962,代表ARRAY_BUFFER 顶点索引 vertex indices, 34963,代表ELEMENT_ARRAY_BUFFER | 
该bufferViews包含多个buffer
第一个buffer,数据索引0,偏移量0,字节长度56332
第二个buffer,数据索引0,偏移量56332,字节长度110220,缓冲类型:属性
第三个buffer,数据索引0,偏移量166552,字节长度73480,缓冲类型:属性
第四个buffer,数据索引0,偏移量240032,字节长度36594,缓冲类型:属性

buffers
buffers是buffer数组,每一个buffer存放真是数据,通常包含bytelength、uri、name字段,后两个不是必须的,将各属性打包成字节,通过偏移地址标记
| 名称 | 说明 | 
|---|---|
| byteLength | buffer字节长度 | 
| uri | buffer的二进制文件地址(非必须) | 
| name | 名称(非必须) | 
该buffers包含一个buffer
该buffer的字节长度为739328

materials
materials包含了模型绘制时需要的纹理信息
基础颜色必须包含使用 sRGB 光电传递函数编码的 8 位值,因此 RGB 值在用于任何计算之前必须解码为实际线性值。
金属度和粗糙度属性的纹理打包纹理中。其绿色通道包含粗糙度值,蓝色通道包含金属度值。此纹理必须使用线性传递函数进行编码,并且每个通道可以使用超过 8 位的位
| 名称 | 说明 | 
|---|---|
| pbrMetallicRoughness | PBR相关参数 | 
| baseColorTexture | 基础颜色,index对应texture的索引 | 
| metallicFactor | 0~1,材质的金属度 | 
| roughnessFactor | 0~1,材质的粗糙度 | 
| extensions | 扩展库属性 | 
扩展属性
| 名称 | 说明 | 
|---|---|
| KHR_draco_mesh_compression | glTF 格式几何压缩库 | 
| KHR_lights_punctual | 场景灯光,光源 | 
| KHR_materials_anisotropy | 材料各项异性 | 
| KHR_materials_clearcoat | 材料透明层 | 
| KHR_materials_emissive_strength | 材料发光的颜色和强度 | 
| KHR_materials_ior | 材料折射率 | 
| KHR_materials_iridescence | 材料薄膜厚度和折射率 | 
| KHR_materials_sheen | 材料光泽 | 
| KHR_materials_specular | 材料粗糙度中的镜面反射和镜面颜色 | 
| KHR_materials_transmission | 薄壳材料的光学透明度 | 
| KHR_materials_unlit | 无光照着色模型 | 
该材料属性,其包含多个PBR属性,
第一个PBR金属模型粗糙度,基础颜色索引0,金属度0,粗糙度0.5,扩展属性是无光照着色模型
第二个PBR金属模型粗糙度,基础颜色索引1,金属度0,粗糙度0.5,扩展属性是无光照着色模型
第三个PBR金属模型粗糙度,基础颜色索引2,金属度0,粗糙度0.5,扩展属性是无光照着色模型

textures
textures对应纹理信息,用于渲染对象的:纹理由材料引用以定义基本物体的颜色以及物理特性
包含两个参数source 对应纹理照片;sampler采样器
| 名称 | 说明 | 
|---|---|
| source | 照片纹理 | 
| sampler | 采样器 | 
textures包含多个纹理
第一个纹理,照片索引0,采样器索引0
第二个纹理,照片索引1,采样器索引1
第三个纹理,照片索引2,采样器索引2

images
图片资源
| 名称 | 说明 | 
|---|---|
| name | 名称 | 
| uri | 指向纹理文件(对glb文件为空,通过给出的"bufferView"的索引) | 
| bufferView | 纹理对应的索引 | 
| mimeType | 图片格式 | 
该images图片资源包括7个
图片1,图片索引0,图片格式jpeg
图片2,图片索引4,图片格式jpeg
图片3,图片索引8,图片格式jpeg

samplers
采样器,对应照片的滤波和环绕方式
| 名称 | 说明 | 
|---|---|
| magFilter | 模型放大时,纹理滤波方式 | 
| minFilter | 模型缩小时,纹理滤波方式 | 
| wrapS | 纹理环绕方式 | 
| wrapT | 纹理环绕方式 | 
滤波方式
| 名称 | 值 | 说明 | 
|---|---|---|
| GL_NEAREST | 9728 | 最临近插值(临近那个就是那个,单色) | 
| GL_LINEAR | 9729 | 线性插值(使用周围多个线性插值,混合色) | 
| GL_NEAREST_MIPMAP_NEAREST | 9984 | 最邻近的mipmap级别,临近插值采样 | 
| GL_LINEAR_MIPMAP_NEAREST | 9985 | 最邻近的mipmap级别,线性插值采样 | 
| GL_NEAREST_MIPMAP_LINEAR | 9986 | 两个最匹配像素的mipmap间线性插值,使用临近插值采样 | 
| GL_LINEAR_MIPMAP_LINEAR | 9987 | 两个最匹配像素的mipmap间线性插值,使用线性插值采样 | 
环绕方式
对纹理坐标范围超出对应纹理时的处理方式,即就是纹理坐标范围是0~1,当纹理坐标超出该值的处理方式
| 名称 | 值 | 说明 | 
|---|---|---|
| GL_CLAMP_TO_EDGE | 33071 | 忽略边缘,超出部分直接使用边缘纹理,1.1处纹理使用1 | 
| GL_MIRRORED_REPEAT | 33648 | 重复纹理,不过重复的图片是镜像方式的 | 
| GL_REPEAT | 10497 | 重复纹理,即1.1处纹理和0.1处纹理一致 | 
该处的采样器集合samplers,包含多个采样器,其采样器对应值一致
模型放大时滤波器使用线性插值,模型缩小时滤波器使用线性插值。






![AV1 Bitstream  Decoding Process Specification--[9]:语法结构语义-5](https://i-blog.csdnimg.cn/direct/02970c1c2da74f57aa50313dcf0cba19.png)













