BabylonJS/Babylon.js · error

Vertex buffers pointing to the same buffer must have the sam

Error message

Vertex buffers pointing to the same buffer must have the same byte stride

What it means

When several vertex buffers share one underlying Buffer, the exporter must write the raw bytes once and describe each view with a byteStride. If the views referencing the same buffer declare different byteStrides, the single glTF bufferView layout would be ambiguous/incorrect, so the exporter throws instead of emitting a corrupted asset.

Source

Thrown at packages/dev/serializers/src/glTF/2.0/glTFExporter.ts:1038

        }

        const buffers = Array.from(bufferToVertexBuffersMap.keys());

        for (const buffer of buffers) {
            const data = buffer.getData();
            if (!data) {
                throw new Error("Buffer data is not available");
            }

            const vertexBuffers = bufferToVertexBuffersMap.get(buffer);

            if (!vertexBuffers) {
                continue;
            }

            const byteStride = vertexBuffers[0].byteStride;
            if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {
                throw new Error("Vertex buffers pointing to the same buffer must have the same byte stride");
            }

            const bytes = DataArrayToUint8Array(data).slice();

            // Apply normalizations and color corrections to buffer data in-place.
            for (const vertexBuffer of vertexBuffers) {
                const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;
                const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);

                switch (kind) {
                    // Normalize normals and tangents.
                    case VertexBuffer.NormalKind:
                    case VertexBuffer.TangentKind: {
                        EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {
                            const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
                            if (length > 0) {
                                const invLength = 1 / length;
                                values[0] *= invLength;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Make all vertex buffers sharing the same Buffer use the same byteStride value
  2. Split attributes with a different stride into their own separate Buffer instance so each buffer has a consistent stride
  3. Repack/rebuild the vertex data into a single consistent interleaved layout (or non-interleaved) before exporting
  4. Catch the error and export after normalizing the geometry

Example fix

// before
new VertexBuffer(engine, data, VertexBuffer.PositionKind, true, 0, 20); // stride 20
new VertexBuffer(engine, data, VertexBuffer.NormalKind, true, 8, 16);   // stride 16, same buffer
// after
new VertexBuffer(engine, data, VertexBuffer.PositionKind, true, 0, 20);
new VertexBuffer(engine, data, VertexBuffer.NormalKind, true, 12, 20);  // same stride 20 on same buffer
Defensive patterns

Strategy: validation

Validate before calling

function stridesConsistent(bufferToVertexBuffers: Map<IUnknown, IVertexBuffer[]>): boolean {
    for (const [, vbs] of bufferToVertexBuffers) {
        const s = vbs[0].byteStride;
        if (vbs.some((vb) => vb.byteStride !== s)) return false;
    }
    return true;
}

Try / catch

try {
    await GLTF2Export.GLTFAsync(scene, "scene");
} catch (e) {
    if (e instanceof Error && e.message.startsWith("Vertex buffers pointing to the same buffer")) {
        // normalize strides and retry export
    } else { throw e; }
}

Prevention

When it happens

Trigger: Registering multiple VertexBuffers that point to the same Buffer instance but were created with different byteStride values (e.g. interleaved position+uv with stride 20 plus a separately interleaved set with stride 16) and exporting them via GLTFExporter.

Common situations: Manual interleaved-vertex-buffer setups where some attributes were packed with different strides; merging meshes whose custom vertex layouts differ; a refactoring that changed stride for one attribute but not others sharing the buffer.

Related errors


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