bevyengine/bevy · error · MeshAttributeCompressionError

Vertex attribute {attr:?} must have format `Float32`, `Float

Error message

Vertex attribute {attr:?} must have format `Float32`, `Float32x2` or `Float32x4` before quantizing

What it means

MeshAttributeCompressionError::UnsupportedAttributeForQuantizing is thrown when quantizing an attribute whose VertexFormat is not Float32, Float32x2, or Float32x4. Quantization operates on raw floating-point components, so the library requires one of these three source formats.

Source

Thrown at crates/bevy_mesh/src/mesh.rs:3188

        }
    }
}

/// Error that can occur when compressing/quantizing mesh vertex attributes.
#[derive(Error, Debug, Clone)]
pub enum MeshAttributeCompressionError {
    #[error("Vertex attribute {0:?} doesn't exist")]
    MissingAttribute(MeshVertexAttributeId),
    #[error("Vertex attribute {0:?} must not be empty")]
    EmptyAttribute(MeshVertexAttribute),
    #[error(
        "Vertex attribute {attr:?} must have format {expected:?} before compressing/quantizing"
    )]
    UnsupportedAttributeForCompression {
        attr: MeshVertexAttribute,
        expected: VertexFormat,
    },
    #[error("Vertex attribute {attr:?} must have format `Float32`, `Float32x2` or `Float32x4` before quantizing")]
    UnsupportedAttributeForQuantizing { attr: MeshVertexAttribute },
}

/// Error that can occur when calling [`Mesh::merge_duplicate_vertices`]
#[derive(Error, Debug, Clone)]
pub enum MeshMergeDuplicateVerticesError {
    #[error("Index attribute already set.")]
    IndicesAlreadySet,
    #[error("Mesh access error: {0}")]
    MeshAccessError(#[from] MeshAccessError),
}

/// Error that can occur when calling [`Mesh::merge`].
#[derive(Error, Debug, Clone)]
pub enum MeshMergeError {
    #[error("Incompatible vertex attribute types: {} and {}", self_attribute.name, other_attribute.map(|a| a.name).unwrap_or("None"))]
    IncompatibleVertexAttributes {
        self_attribute: MeshVertexAttribute,

View on GitHub (pinned to 8d743eb7dc)

Solutions

  1. Ensure the attribute is in a Float32, Float32x2, or Float32x4 format (convert first if needed) before calling quantize_attribute
  2. Check the format before quantizing: mesh.attribute(id).map(|a| a.format()) and only quantize when it matches
  3. Do not quantize attributes that are already in a compressed/normalized format — skip them in your pipeline
  4. Fix the insert_attribute call to use the intended float VertexFormat when constructing the mesh

Example fix

// before
mesh.quantize_attribute(attr_id); // attr format is Float32x3
// after
let fmt = mesh.attribute(attr_id).map(|a| a.format());
if matches!(fmt, Some(VertexFormat::Float32 | VertexFormat::Float32x2 | VertexFormat::Float32x4)) {
    mesh.quantize_attribute(attr_id);
}
Defensive patterns

Strategy: validation

Validate before calling

fn quantizable(mesh: &Mesh, id: MeshVertexAttributeId) -> bool {
    matches!(
        mesh.attribute(id).map(|a| a.format()),
        Some(VertexFormat::Float32 | VertexFormat::Float32x2 | VertexFormat::Float32x4)
    )
}

Try / catch

match result {
    Err(MeshAttributeCompressionError::UnsupportedAttributeForQuantizing { attr }) => {
        warn!("{:?} not float32*; skipping quantize", attr);
    }
    _ => {}
}

Prevention

When it happens

Trigger: Calling Mesh::quantize_attribute on an attribute stored in any format other than Float32/Float32x2/Float32x4 — e.g. already-quantized Snorm/Unorm formats, integer formats, or a half-float format.

Common situations: Quantizing an attribute that was already quantized in a previous processing pass; meshes imported with normalized integer vertex formats from glTF/FBX; hand-built meshes inserted with the wrong VertexFormat.

Related errors


AI-assisted analysis of bevyengine/bevy@8d743eb7dc (2026-09-13). Data as JSON: /api/errors/afe4370a227dee6a. Report an issue: GitHub.