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 is 4 (TRIANGLES).
  • indices: An optional integer referencing an accessor that 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 0 serves 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.