Complete
Written against the glTF 1.0 spec. This extension is no longer needed in glTF 2.0 as glTF 2.0 includes GLB File Format Specification.
glTF provides two delivery options that can also be used together:
For these resources, glTF requires either separate requests or extra space due to base64-encoding. Base64-encoding requires extra processing to decode and increases the file size (by ~33% for encoded resources). While gzip mitigates the file size increase, decompression and decoding still add significant loading time.
To solve this, this extension introduces a container format, Binary glTF.
In Binary glTF, a glTF asset (JSON, .bin, images, and shaders) can be stored in a binary blob accessed in JavaScript as an ArrayBuffer
.
This binary blob (which can be a file, for example) is divided into three subsequent parts:
header
content
body
The content
part can refer to external resources as usual, and can also reference resources stored within the binary body
.
Binary glTF is little endian and strings are encoded using UTF-8. Figure 1 shows an overview of the three parts of a Binary glTF asset.
Figure 1: Binary glTF layout.
The following sections describe the structure of the three parts more in detail.
The 20-byte header consists of the following five 4-byte entries:
magic
is the ASCII string 'glTF'
, and can be used to identify the arraybuffer as Binary glTF.
version
is an uint32
that indicates the version of the Binary glTF container format. Currently available versions are shown in Table 1.
length
is the total length of the Binary glTF, including header
, content
, and body
, in bytes.
contentLength
is the length, in bytes, of the glTF content
. It must be greater than zero.
contentFormat
specifies the format of the glTF content
. A list of all valid values currently available is in Table 2.
Table 1: Valid values for version
Decimal | Hex | Description |
---|---|---|
1 | 0x00000001 | Version 1 |
Table 2: Valid values for contentFormat
Decimal | Hex | Description |
---|---|---|
0 | 0x00000000 | JSON |
The content
part holds the structured glTF content description, as it would be provided within a .gltf file in glTF without this extension.
In a JavaScript implementation, the TextDecoder
API can be used to extract the glTF content from the arraybuffer, and then the JSON can be parsed with JSON.parse
as usual.
By reading the content
first, an implementation is able to progressively retrieve resources from the binary body.
This way, it is also possible to read only a selected subset of resources from a Binary glTF asset (for instance, the coarsest LOD of a mesh).
Elements of the content
can refer to binary data within the body
, using a special buffer with an id equal to "binary_glTF"
.
For more details, see glTF Schema Updates below.
Binary glTF still supports external resources. For example, an application that wants to download textures on demand may embed everything except images in the Binary glTF. Embedded base64-encoded resources are also still supported, but it would be inefficient to use them. An advantage of Binary glTF over glTF is that resources can be embedded without paying the size and client-side decoding costs of base64-encoding.
The binary body
is the binary payload for geometry, animation key frames, skins, images, and shaders.
The start of body
is 4-byte aligned to ease its use with JavaScript Typed Arrays. This implies that trailing spaces may be added to the JSON in the content
part such that (20 + contentLength)
is divisible by 4
.
The buffer with id equal to "binary_glTF"
is used to address the content of the binary body
.
An offset of zero addresses the first byte of the binary body
.
As mentioned above, Binary glTF introduces a buffer
with id equal to "binary_glTF"
.
This buffer is an implicit reference to the binary body
of the Binary glTF asset.
Its type
property is "arraybuffer"
, and a runtime can ignore the uri
property since the buffer refers to the Binary glTF body
section, not an external resource.
When a runtime encounters this buffer, it should use the Binary glTF body
as the buffer.
bufferViews
that reference this buffer
work as usual.
To support embedded shaders and images, shader
and image
glTF properties have new KHR_binary_glTF
extension properties that should be used instead of the uri
property.
See Listings 2 and 3.
Listing 2: A shader
referencing a bufferView
to access an embedded shader source.
"extensionsUsed" : [
"KHR_binary_glTF"
]
// ...
"a_shader" : {
"extensions" : {
"KHR_binary_glTF" : {
"bufferView" : // ...
}
}
}
Listing 3: An image
referencing a bufferView
and with metadata useful for loading the image from the arraybuffer. In JavaScript, Blob
can be used as the source for an Image
to extract an image from the arraybuffer (see Cesium’s loadImageFromTypedArray
helper function).
"extensionsUsed" : [
"KHR_binary_glTF"
]
// ...
"an_image" : {
"extensions" : {
"KHR_binary_glTF" : {
"bufferView" : // ...,
"mimeType" : "image/png",
"height" : 256,
"width" : 512
}
}
}
For full details on the KHR_binary_glTF
extension properties, see the schema:
The file extension to be used with Binary glTF is .glb
.
Use model/gltf.binary
.
This section is non-normative.
Based on experimentation (below & [1]) using CESIUM_binary_glTF (only trivial differences to KHR_binary_glTF) and the glTF loader in Cesium 1.10, different configurations are recommended for different scenarios.
The following observations are made from file size and benchmark data:
Using the Cesium aircraft model, which contains 5,984 triangles with two texture atlases and a simple animation without skinning, statistics and results for the common glTF setups are:
Cesium Air | # files | size | size (gzip*) | load time |
---|---|---|---|---|
COLLADA | 3 | 922 KiB | 591 KiB | |
glTF | 8 | 608 KiB | 538 KiB | 0.32 s |
glTF, base64-encoded bin/jpg/png/glsl | 1 | 808 KiB | 540 KiB | 0.41 s |
Binary glTF, embedded textures | 1 | 609 KiB | 513 KiB | 0.29 s |
Binary glTF, separate textures | 3 | 609 KiB | 538 KiB | 0.30 s |
Using the 1200 12th Ave model (thanks to Cube Cities), which contians 30,235 triangles with 21 textures and no animations, statistics and results for the common glTF setups are:
1200 12th Ave | # files | size | size (gzip*) | load time |
---|---|---|---|---|
COLLADA | 22 | 5.93 MiB | 1.36 MiB | |
glTF | 31 | 2.99 MiB | 1.25 MiB | 0.85 s |
glTF, base64-encoded bin/jpg/png/glsl | 1 | 3.64 MiB | 1.30 MiB | 1.25 s |
Binary glTF, embedded textures | 1 | 2.99 MiB | 1.23 MiB | 1.03 s |
Binary glTF, separate textures | 22 | 2.99 MiB | 1.25 MiB | 0.84 s |
* All files gzipped except for stand-alone images.