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:
- Locate the primitive's
attributes.POSITIONinteger index. - Read the corresponding accessor object from the glTF
accessorsarray. - Extract
accessor.minas the box minimum vector: \(V_{min} = (min_x, min_y, min_z)\). - Extract
accessor.maxas 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:
Calculate the Center:
\(Center = \frac{V_{min} + V_{max}}{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:
- 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, andscale, or thematrixproperty) to determine the world matrix (\(M\)). - 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.
- 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.