GLB是GLTF模型的二进制文件格式表示。GLTF的node层次结构、mesh、材质、动画等信息都用二进制信息表示。
GLB文件主要包括Header和Chunks两部分,文件结构示意图如下

Header
GLB文件的头部包含3部分,每部分由4 bytes组成,共12 bytes:
- unit32 magic - GLTF标识符,数值为 0x46546C67,gltf的ASCII码值
- unit32 version - GLTF版本号
- unit32 length - GLB文件的大小,包括header和所有chunks的字节长度
Chunks
|
uint32 |
uint32 |
ubyte[] |
|---|---|---|
| chunkLength | chunkType | chunkData |
- chunkLength - chunkData的长度
- chunkType - chunk的类型,主要有JOSN和BIN(对应我们平时的scene.gltf和scene.bin的数据)
- chunkData - chunk的binary数据
chunk Type
|
Chunk Type |
ASCII |
Description |
|---|---|---|
| 0x4E4F534A | JSON | Structured JSON content |
| 0x004E4942 | BIN | Binary buffer |
这里展示用python加载glb格式到json和bytes字节(对应gltf的bin文件)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | def __load_glb__(file_name): gltf_json = None gltf_buffers = [] with open(file_name, 'rb') as f: # glb-header:12-byte # uint32 magic - magic equals 0x46546C67. It is ASCII string glTF, and can be used to identify data as Binary glTF # uint32 version - indicates the version of Binary glTF container format # uin32 length - the total length of the Binary glTF, including Header and all chunks in bytes b = f.read(GLB_HEADER_BYTE_LENGTH) magic = b[0:4] if magic != b'glTF': raise RuntimeError('File is not a valid GLB file') version, = struct.unpack_from('<I', b, 4) if version != 2: raise RuntimeError('Unsupported GLB file version: '+str(version)+'. Only version 2 is currently supported') byte_len, = struct.unpack_from('<I', b, 8) # glb_chunk_array: have 1 json chunk and 0 or 1 bin chunk # uint32 chunk_length:length of chunk_data in bytes # uint32 chunk_type: json and bin # ubyte chunk_data: binary payload of chunk # 不使用while,定义最大的循环为1024*1024 for i in range(1024*1024): b = f.read(GLB_CHUNK_HEADER_BYTE_LENGTH) if b == b'': break if len(b) != 8: raise RuntimeError('Unexpected EOF when processing GLB chunk header. Chunk header must be 8 bytes') chunk_length, = struct.unpack_from('<I', b, 0) chunk_type, = struct.unpack_from('<I', b, 4) if chunk_length == 0: raise RuntimeError('chunk may not be empty') chunk_data = f.read(chunk_length) if chunk_type == GLB_JSON_CHUNK_TYPE: gltf_json = json.loads(chunk_data.decode('utf-8').strip()) elif chunk_type == GLB_BINARY_CHUNK_TYPE: gltf_buffers.append(chunk_data) else: raise RuntimeError('chunk type error') return gltf_json, gltf_buffers |