Search code examples
graphics3dgltf

Why are BufferViews and Accessors separate in glTF?


The GLTF format specifies that meshes reference their vertex and index data via accessors, which in turn reference BufferViews. Both of them have an offset and a length.

The main difference seems to be that BufferViews are format-agnostic, they just reference a bunch of bytes, while the accessors are adding type information.

What I do not understand is:

  1. Why do both of them need an offset and a length? Which use case is there where the offset in an accessor is not zero and the count of an accessor does not correspond to the length of the view?
  2. Why isn't the type data directly contained in the buffer view? In what use case does it make sense to interpret the same data with different formats?

Solution

  • The format is designed to support interleaved vertex attributes, initially from WebGL (in glTF 1.0) but now more generally across graphics APIs (in glTF 2.0).

    For example, POSITION data may be a vec3 of FLOAT, but TEXCOORD_0 data may be a vec2 of FLOAT, and there could even be custom attributes of different types, all interleaved within a single GPU buffer.

    So the BufferView defines a given byte stride, and the individual accessors into that view may have different types and amounts but will all share the same byte stride.

    You're not required to interleave of course, but the format is designed to allow it, and to enforce the byte stride sharing when it happens.

    Here's a diagram from the Data Interleaving section of the glTF tutorial. It's a little small here but you can click for a larger view. In this example, there are two accessors, one for POSITION and one for NORMAL, sharing a single BufferView.

    Data Interleaving