FyroxEngine/Fyrox · error

Vertex size must match!

Error message

Vertex size must match!

What it means

When batching meshes (Mesh::batch / push), source vertices are transformed and pushed into the batch's vertex buffer. push_vertex_raw requires each vertex's byte size to exactly match the batch buffer's declared layout. A mismatch means the source mesh's vertex format differs from the destination batch's, which the code treats as a hard error and panics.

Solutions

  1. Ensure all meshes being batched share an identical vertex layout (same attributes, order, and sizes)
  2. Call vertex_buffer.set_vertex_format with the batch's layout descriptor on source meshes before merging, or re-create source buffers with the batch layout
  3. Re-export/re-save legacy meshes with the current engine's default vertex format

Example fix

// before
let mut vb = VertexBuffer::new(vertex_count, vertices); // default layout

// after
let mut vb = VertexBuffer::new(vertex_count, vertices)?;
vb.set_vertex_format(&[VertexAttribute::new(...)])?; // match batch layout
Defensive patterns

Strategy: validation

Validate before calling

if src_data.vertex_buffer.layout() != batch_vertex_buffer.layout() { /* abort merge with clear error */ }

Type guard

fn layouts_match(src: &VertexBuffer, dst: &VertexBuffer) -> bool { src.layout() == dst.layout() }

Try / catch

// compare vertex layouts before batching; panics indicate mismatched formats
assert_eq!(src_data.vertex_buffer.layout(), batch_vertex_buffer.layout(), "vertex layout mismatch");

Prevention

When it happens

Trigger: Merging meshes whose vertex buffers were created with different VertexFormat layouts (different attribute sets, ordering, or sizes); pushing vertices into a manually-created batch buffer with the wrong layout.

Common situations: Batching static meshes that were built with different custom vertex formats; a mesh saved by an older engine version with a legacy layout being merged into a new-format batch; procedural meshes forgetting to call set_vertex_format to match the target.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/01ee416b5fcb6c59. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-impl/src/scene/mesh/mod.rs:273

                ResourceKind::Embedded,
                SurfaceData::new(
                    src_data.vertex_buffer.clone_empty(4096),
                    TriangleBuffer::new(Vec::with_capacity(4096)),
                ),
            ),
            material: material.clone(),
        });

        let mut batch_data_guard = batch.data.data_ref();
        let batch_data = &mut *batch_data_guard;
        let start_vertex_index = batch_data.vertex_buffer.vertex_count();
        let mut batch_vertex_buffer = batch_data.vertex_buffer.modify();
        for src_vertex in src_data.vertex_buffer.iter() {
            batch_vertex_buffer
                .push_vertex_raw(&src_vertex.transform(&mut |vertex| {
                    transform_vertex(vertex, &instance_data.world_transform)
                }))
                .expect("Vertex size must match!");
        }

        let mut batch_geometry_buffer = batch_data.geometry_buffer.modify();
        batch_geometry_buffer.push_triangles_with_offset(
            start_vertex_index,
            src_data.geometry_buffer.triangles_ref(),
        );
    }
}

/// Mesh is a 3D model, each mesh split into multiple surfaces, each surface represents a patch of the mesh with a single material
/// assigned to each face. See [`Surface`] docs for more info.
///
/// ## How to create
///
/// Usually there is no need to manually create meshes, it is much easier to make one in a 3d modelling software or just download
/// some model you like and load it in engine. See [`crate::resource::model::Model`] docs for more info about model resources.
///

View on GitHub (pinned to 76c91aad8e)