GLB是GLTF模型的二進制檔案格式表示。GLTF的node層次結構、mesh、材質、動畫等資訊都用二進制資訊表示。
GLB檔案主要包括Header和Chunks兩部分,檔案結構示意圖如下
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL9UFRNNTUU9EMRRVT3V1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1kjM2QTOxUTM5IjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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檔案)
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