Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Meshes and Vertices

Mesh<V> is a vertex + index buffer asset, generic over vertex type — V defaults to the built-in Vertex (position, UV, normal, tangent), but any bytemuck::Pod struct works:

fn setup(backend: Read<Backend>, mut meshes: Write<Assets<Mesh>>) {
    let vertices = vec![/* Vertex { .. } */];
    let indices = vec![0, 1, 2, /* ... */];
    let handle = Mesh::new(vertices, indices).build_asset("cube", &mut meshes);
}

The uploaded GPUMesh has public vertex_buffer/index_buffer (both plain Buffer) and index_count, ready to pass to set_vertex_buffer/set_index_buffer/draw_indexed — see Recording a Render Pass.

CPU-side access

vertices()/indices() return the CPU-side source data — e.g. for building a collision mesh from the same data used to render it. release_cpu_data() frees that copy once you’re done reading it, but unlike other asset types, a released mesh can never be re-uploaded — if the GPU backend is ever lost and recreated afterward, this mesh logs an error and simply stays not-ready forever. Only call it if that’s acceptable for this particular mesh.

Custom vertex types

#[repr(C)]
#[derive(Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)]
struct MyVertex {
    position: glam::Vec3,
    color: glam::Vec4,
}

impl MyVertex {
    fn layout() -> VertexBufferLayout {
        VertexBufferLayout {
            array_stride: std::mem::size_of::<MyVertex>() as u64,
            step_mode: VertexStepMode::Vertex,
            attributes: vec![
                VertexAttribute { format: VertexFormat::Float32x3, offset: 0, shader_location: 0 },
                VertexAttribute { format: VertexFormat::Float32x4, offset: 12, shader_location: 1 },
            ],
        }
    }
}

Pass MyVertex::layout() to Material::with_vertex_layouts (see Materials) so the pipeline’s vertex stage matches.

Instancing

InstanceVertex carries just a model matrix, for instanced draws — bind it alongside a regular vertex buffer at VertexStepMode::Instance, then pass an instance range to draw/draw_indexed instead of 0..1.