glTF Indexing Modes for Triangle Topologies
This article provides an overview of how the glTF (GL Transmission Format) specification defines topology types and index modes for rendering triangular meshes. In glTF, primitive geometry can be represented either with explicit index buffers or sequentially through implicit vertex order, using specific enumeration values to designate triangle lists, triangle strips, and triangle fans. Below is a breakdown of how the specification structures these topologies and their corresponding indexing mechanisms.
The Mesh Primitive Structure
In glTF, all geometric objects are defined inside the
primitives array of a mesh object. Each
primitive contains two key properties that govern its topology and
indexing behavior:
mode: An integer defining the draw topology. The default value is4(TRIANGLES).indices: An optional integer referencing anaccessorthat holds index data.
If the indices property is defined, the primitive is
indexed. If indices is omitted, the
primitive is non-indexed, and vertices are read
sequentially from the attribute buffers starting from index
0.
Index Accessor Requirements
When indices is defined, the referenced
accessor object must satisfy specific constraints:
type: Must be"SCALAR".componentType: Must be an unsigned integer format:5121(UNSIGNED_BYTE)5123(UNSIGNED_SHORT)5125(UNSIGNED_INT)
Signed integer and floating-point component types are not permitted for indices.
Triangle Topologies
The glTF specification defines three primary triangular drawing modes
via the mode attribute, corresponding directly to standard
WebGL and OpenGL drawing modes.
1. Triangle Lists
(TRIANGLES, Mode 4)
TRIANGLES is the standard and most common rendering mode
in glTF. Every set of three consecutive indices forms an independent
triangle.
- Indexed Mode: The index buffer is read sequentially in groups of three. Triangle \(k\) is formed by vertices referenced at index positions \(3k\), \(3k+1\), and \(3k+2\).
- Non-Indexed Mode: Triangle \(k\) is constructed directly using vertex buffer offsets \(3k\), \(3k+1\), and \(3k+2\).
- Vertex Count: The total number of indices (or vertices, if non-indexed) must be a multiple of 3.
2. Triangle Strips
(TRIANGLE_STRIP, Mode 5)
In a triangle strip, vertices are shared between adjacent triangles to minimize data redundancy. After the first triangle is established, each subsequent vertex forms a new triangle with the preceding two vertices.
- Indexed Mode: Triangle \(k\) is formed by reading three consecutive index entries: \((k, k+1, k+2)\) from the index accessor.
- Non-Indexed Mode: Triangle \(k\) is formed by vertices \((k, k+1, k+2)\) read directly from the vertex attributes.
- Winding Order: To maintain consistent face orientation (counter-clockwise by default), the winding order implicitly alternates on odd-numbered triangles (\(k=1, 3, 5, \dots\)) as \((k+1, k, k+2)\).
- Minimum Elements: Requires at least 3 indices or vertices. A strip with \(n\) elements yields \(n - 2\) triangles.
3. Triangle Fans
(TRIANGLE_FAN, Mode 6)
A triangle fan shares a single origin vertex among all triangles in the set.
- Indexed Mode: The very first index in the index
buffer (index 0) serves as the central hub. Triangle \(k\) (starting at \(k = 0\)) is constructed using the index at
position
0, followed by the indices at positions \(k+1\) and \(k+2\). - Non-Indexed Mode: Vertex
0serves as the central hub, forming triangle \(k\) using vertices \(0\), \(k+1\), and \(k+2\). - Minimum Elements: Requires at least 3 elements, producing \(n - 2\) triangles for \(n\) elements.
Primitive Restart
Standard glTF 2.0 does not support primitive restart tokens (such as
0xFFFF or 0xFFFFFFFF) within index buffers to
break strips or fans into separate sub-topologies. Multi-part surfaces
using strips or fans must be split across multiple primitives within the
same mesh.