BabylonJS/Babylon.js · error · Error

${extensionContext}/attributes: Instance buffer accessors do

Error message

${extensionContext}/attributes: Instance buffer accessors do not have the same count.

What it means

EXT_mesh_gpu_instancing requires all instance attribute accessors (TRANSLATION, ROTATION, SCALE, custom ones) to describe the same number of instances. loadAttribute compares each accessor.count to the first one seen; a mismatch throws, since per-instance buffers of differing lengths cannot be interleaved into an instanced draw.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.ts:76

                return await promise;
            }

            const promises = new Array<Promise<Nullable<Float32Array>>>();
            let instanceCount = 0;

            const loadAttribute = (attribute: string) => {
                if (extension.attributes[attribute] == undefined) {
                    promises.push(Promise.resolve(null));
                    return;
                }

                const accessor = ArrayItem.Get(`${extensionContext}/attributes/${attribute}`, this._loader.gltf.accessors, extension.attributes[attribute]);
                promises.push(this._loader._loadFloatAccessorAsync(`/accessors/${accessor.bufferView}`, accessor));

                if (instanceCount === 0) {
                    instanceCount = accessor.count;
                } else if (instanceCount !== accessor.count) {
                    throw new Error(`${extensionContext}/attributes: Instance buffer accessors do not have the same count.`);
                }
            };

            loadAttribute("TRANSLATION");
            loadAttribute("ROTATION");
            loadAttribute("SCALE");
            loadAttribute("_COLOR_0");

            // eslint-disable-next-line github/no-then
            return await promise.then(async (babylonTransformNode) => {
                const [translationBuffer, rotationBuffer, scaleBuffer, colorBuffer] = await Promise.all(promises);
                const matrices = new Float32Array(instanceCount * 16);
                TmpVectors.Vector3[0].copyFromFloats(0, 0, 0); // translation
                TmpVectors.Quaternion[0].copyFromFloats(0, 0, 0, 1); // rotation
                TmpVectors.Vector3[1].copyFromFloats(1, 1, 1); // scale
                for (let i = 0; i < instanceCount; ++i) {
                    translationBuffer && Vector3.FromArrayToRef(translationBuffer, i * 3, TmpVectors.Vector3[0]);
                    rotationBuffer && Quaternion.FromArrayToRef(rotationBuffer, i * 4, TmpVectors.Quaternion[0]);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Regenerate all instance attribute accessors so every one has the same count
  2. Remove the mismatched attribute from extension.attributes
  3. Re-export the instanced asset from the source tool
  4. Validate with glTF-Validator to catch count mismatches before load

Example fix

// before
"attributes": { "TRANSLATION": 5, "ROTATION": 6 } // accessor counts differ
// after: ensure accessors 5 and 6 both have count = N (same instance count)
Defensive patterns

Strategy: validation

Validate before calling

const ext = node.extensions?.EXT_mesh_gpu_instancing;
if (ext) {
  const counts = Object.values(ext.attributes).map(i => gltf.accessors[i].count);
  if (new Set(counts).size !== 1) throw new Error('Instance accessors have differing counts');
}

Try / catch

try {
  await BABYLON.SceneLoader.LoadAsync('./', 'instanced.gltf', engine);
} catch (e) {
  if (e instanceof Error && e.message.includes('same count')) {
    console.error('Fix instance attribute accessor counts to match');
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a glTF whose node's EXT_mesh_gpu_instancing extension declares attributes with accessors of different counts (e.g. 100 translations but 50 rotations).

Common situations: Hand-assembled instancing extension blocks where custom attribute accessors were added with a different instance count; tool export bugs; partially updated assets after editing instance data.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/16dd27e50e02c750. Report an issue: GitHub.