Extract Bounding Volumes from glTF Accessor Bounds

This article explains how to compute lightweight bounding volumes—such as Axis-Aligned Bounding Boxes (AABBs) and bounding spheres—directly from glTF accessor metadata without parsing binary vertex buffers. By reading the precomputed minimum and maximum vertex bounds defined within glTF JSON structures, applications can instantly generate spatial boundaries for frustum culling, raycasting, and scene organization with minimal memory and processing overhead.

Accessing the Precomputed Metadata

In the glTF 2.0 specification, the POSITION attribute accessor of any mesh primitive is required to declare min and max properties. These properties contain the lower-bound [minX, minY, minZ] and upper-bound [maxX, maxY, maxZ] coordinates of the vertices referenced by that accessor in local object space.

Because these values are stored directly in the JSON header (.gltf) or the initial JSON chunk of a binary container (.glb), you do not need to read, decompress, or iterate over the binary buffer payloads (bufferViews) to find the spatial extent of a primitive.

Generating an Axis-Aligned Bounding Box (AABB)

To construct a local-space AABB for a single primitive:

  1. Locate the primitive's attributes.POSITION integer index.
  2. Read the corresponding accessor object from the glTF accessors array.
  3. Extract accessor.min as the box minimum vector: \(V_{min} = (min_x, min_y, min_z)\).
  4. Extract accessor.max as the box maximum vector: \(V_{max} = (max_x, max_y, max_z)\).

If a mesh contains multiple primitives, calculate the union of all primitive bounds:

  • \(Mesh_{min} = (\min(min_{x, 1}, min_{x, 2}, \dots), \min(min_{y, 1}, min_{y, 2}, \dots), \min(min_{z, 1}, min_{z, 2}, \dots))\)
  • \(Mesh_{max} = (\max(max_{x, 1}, max_{x, 2}, \dots), \max(max_{y, 1}, max_{y, 2}, \dots), \max(max_{z, 1}, max_{z, 2}, \dots))\)

Deriving a Bounding Sphere

A basic bounding sphere can be approximated directly from the extracted \(V_{min}\) and \(V_{max}\) vectors:

  1. Calculate the Center:
    \(Center = \frac{V_{min} + V_{max}}{2}\)

  2. Calculate the Radius:
    \(Radius = \frac{\|V_{max} - V_{min}\|}{2}\)

While this produces an enclosing sphere derived from the box diagonal rather than a minimal bounding sphere fitted strictly to the vertices, it requires zero vertex traversal and suffices for coarse visibility culling.

Transforming Bounds to World Space

glTF accessor bounds represent geometry in local coordinate space. To project these bounds into world space:

  1. Compute the Global Transform: Traverse the scene graph from the root node to the target mesh node, multiplying local transformation matrices (derived from translation, rotation, and scale, or the matrix property) to determine the world matrix (\(M\)).
  2. Transforming the AABB: Transform all eight corners of the local AABB by \(M\). Determine the new world-space AABB by finding the component-wise minimum and maximum of the eight transformed corner vertices.
  3. Transforming the Bounding Sphere: Multiply the local \(Center\) by \(M\). Multiply the local \(Radius\) by the maximum scale factor extracted from the matrix's principal axes:
    \(Scale_{max} = \max(\|M_{col0}\|, \|M_{col1}\|, \|M_{col2}\|)\).

Performance Advantages

Extracting bounds directly from accessors executes in \(O(1)\) time per primitive, bypassing expensive buffer decoding, network streams, or GPU readbacks. This allows graphics engines to perform coarse scene graph traversal, spatial partitioning (such as BVH or Octree generation), and view-frustum culling before geometry buffers are loaded into memory.