Vertex positions, indices, animation keys and other bulk data live in binary buffers. glTF reaches them in three steps: a buffer is a block of bytes, a buffer view is a slice of it, and an accessor says how to read typed elements from a view. All binary data is little-endian. This page follows the Khronos glTF 2.0 specification and its JSON schemas.
Buffers and buffer views
| Object | Property | Meaning |
|---|---|---|
buffer | byteLength | required, at least 1 |
uri | a relative path or a data: URI with base64; omitted for the BIN chunk of a GLB | |
bufferView | buffer | required: which buffer |
byteOffset | default 0 | |
byteLength | required, at least 1 | |
byteStride | 4 to 252, a multiple of 4: the distance between the starts of two vertex elements; omitted for tightly packed data, and required when two or more accessors share the view | |
target | a hint for the GPU buffer: 34962 vertex data (ARRAY_BUFFER), 34963 indices (ELEMENT_ARRAY_BUFFER) |
Accessors
| Property | Meaning |
|---|---|
bufferView | the view; when omitted the elements are all zero (or come only from sparse) |
byteOffset | default 0; a multiple of the component size |
componentType | required: below |
normalized | default false: whether integers stand for 0 to 1 or −1 to 1 |
count | required, at least 1: the number of elements |
type | required: below |
min, max | the smallest and largest value of each component; required for POSITION and for animation inputs |
sparse | values that differ from the base (below) |
| componentType | Type | Size | Normalized value |
|---|---|---|---|
| 5120 | signed byte | 1 | max(c ÷ 127, −1) |
| 5121 | unsigned byte | 1 | c ÷ 255 |
| 5122 | signed short | 2 | max(c ÷ 32,767, −1) |
| 5123 | unsigned short | 2 | c ÷ 65,535 |
| 5125 | unsigned int | 4 | not allowed; only for indices |
| 5126 | float | 4 | not allowed |
| type | Components |
|---|---|
SCALAR | 1 |
VEC2, VEC3, VEC4 | 2, 3, 4 |
MAT2, MAT3, MAT4 | 4, 9, 16, column by column |
Alignment
- An accessor’s offset within its view, and the view’s offset within its buffer taken together, must be a multiple of the component size.
- Every element of a vertex attribute starts on a 4-byte boundary, so a VEC3 of bytes takes 4 bytes in a packed view.
- Each column of a matrix starts on a 4-byte boundary: a MAT2 of bytes takes 8 bytes, a MAT3 of bytes 12 and a MAT3 of shorts 24.
Sparse accessors
sparse stores only the elements that differ from the base data (the
view, or zeros). It has three required parts: count, the number of
changed elements; indices, a bufferView,
byteOffset (default 0) and componentType (5121, 5123 or
5125), listing the changed element numbers in strictly rising order; and
values, a bufferView and byteOffset holding the
new elements, tightly packed, in the accessor’s own type.
Vertex attributes
| Name | Type | Components | Meaning |
|---|---|---|---|
POSITION | VEC3 | float | positions; the accessor needs min and max |
NORMAL | VEC3 | float | unit normals |
TANGENT | VEC4 | float | tangents; w is +1 or −1 and gives the bitangent’s direction |
TEXCOORD_n | VEC2 | float, or normalized unsigned byte or short | texture coordinates |
COLOR_n | VEC3 or VEC4 | float, or normalized unsigned byte or short | linear RGB or RGBA multiplied with the material |
JOINTS_n | VEC4 | unsigned byte or short | indices into the skin’s joints |
WEIGHTS_n | VEC4 | float, or normalized unsigned byte or short | joint weights, adding up to 1 |
Sets are numbered from 0 without gaps (TEXCOORD_0,
TEXCOORD_1…). Application-specific attributes start with an underscore,
such as _TEMPERATURE.
Morph targets
Each target holds differences to add to the base attributes, scaled by its weight:
| Name | Type | Components |
|---|---|---|
POSITION | VEC3 | float |
NORMAL | VEC3 | float |
TANGENT | VEC3 (no handedness) | float |
TEXCOORD_n | VEC2 | float, or normalized signed or unsigned byte or short |
COLOR_n | VEC3 or VEC4 | float, or normalized signed or unsigned byte or short |