Bone Batching in PVRGeoPOD

Bone batching is used to ensure the number of bones per draw call can fit into the uniforms provided by the API

What is bone batching?

A bone is normally represented by a transformation matrix, and is usually uploaded to be used in the API’s shader as one or two transformation matrices.

In older APIs – ones that do not support Uniform or Storage Buffers – such as OpenGL ES 2.0, bone matrices have to be uploaded as uniforms.

Bone batching is a technique used to ensure that the number of bones per draw call can fit into the uniforms provided by the API. The typical number of bones per bone batch is eight.

If bone batching is used, the mesh’s indexes are sorted in such a way that the mesh must be drawn in several calls, one per Bone Batch, each after uploading the specified number of bones. In this case, the bone index attribute for each vertex is a number from 0 to 8, and references the bones in its corresponding batch. Thus, the program is expected to upload the bones for a batch, then draw the corresponding indexes of that butch batch, then upload the next, draw the next, and so on.

Sometimes bone batching is not necessary

Since modern APIs like OpenGL ES 3.x or Vulkan, have access to uniform/storage buffers, this limit does not apply. Any number of bones can comfortably be uploaded in a buffer, and bone-batching can (and should) be safely disabled. In that case, the bones are exported as a single batch, and the bone index attribute for each vertex is a number from 0 to the total number of bones minus one.

In this case, all the bones can be uploaded in a single UBO/SSBO, and the mesh drawn with a single call.

Note that since bones are actually nodes in the scene, a single batch is still required, as the node ID of each bone (with which the user will access the matrix of the bone to upload to the shader) must be mapped to the index of the bone (with which the user will upload it into the Buffer, and is the same as the bone index attribute of the vertices).

In both cases, the node’s transformations need to be loaded into uniform buffer/uniforms in the same order as expressed in the MESHBONEBATCHES list in the POD file.

For example:

MESHBONEBATCHBONEMAX 20,
MESHBONEBATCHCNT 1,
MESHBONEBATCHES 21, 22, 20, 19, 17, 16, 18, 15, 13, 14, 10, 11, 6, 7, 8, 9, 5, 3, 2,
MESHBONEBATCHBONECNTS 20,
MESHBONEBATCHOFFSETS 0

The transformation matrices from Nodes 21, 22, 20, and so on, needs to be loaded in the Uniform Buffer in this exact order. The vertex bone indices will reference them as 0, 1, 2, 3, and so on.