FyroxEngine/Fyrox · error

glTF material failed to import. Reason

Error message

glTF material failed to import. Reason: {err:?}

What it means

When importing a glTF material fails (e.g. bad texture reference or unsupported material feature), the loader logs this error, discards the reason, and substitutes a default white Material with an Embedded resource kind so the rest of the model still loads. Surfaces using that material render untextured/default.

Solutions

  1. Ship all external texture/bin files referenced by the .gltf next to it, or use .glb (self-contained)
  2. Enable the required texture-compression features or re-export textures as PNG/JPEG
  3. Re-export with only core glTF 2.0 PBR material (metallic-roughness) without extra extensions
  4. Check the log for the underlying texture/import error and fix that asset

Example fix

// before: material silently defaulted to white
let model = resource_manager.request::<Model>("scene.gltf");
// after: reassign expected material after load if defaults detected
let model = resource_manager.request::<Model>("scene.gltf");
if let ResourceState::Ok(m) = model.state() {
    for (_, mesh) in m.get_scene().iter().flat_map(|n| n.mesh().into_iter()) {
        for surface in mesh.surfaces() {
            if is_default_white_material(surface.material()) {
                surface.set_material(my_expected_material.clone());
            }
        }
    }
}
Defensive patterns

Strategy: fallback

Validate before calling

// Verify all referenced textures exist before loading a .gltf
let doc = gltf::Gltf::from_slice(&bytes)?;
for image in doc.images() {
    if let gltf::image::Source::Uri { uri, .. } = image.source() {
        assert!(base_dir.join(uri).exists(), "missing texture: {}", uri);
    }
}

Prevention

When it happens

Trigger: import_material during import_from_slice returns Err: referenced texture images missing or unreadable, unsupported PBR extensions, invalid texture coordinates, or texture import/decode failure in the async texture loading step.

Common situations: glb/gltf files referencing external .bin/image files that were not shipped alongside, KTX/basis-compressed textures without the matching feature enabled, exotic material extensions (clearcoat, transmission) unsupported by the engine version.

Related errors


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

Appendix: source

Thrown at fyrox-impl/src/resource/gltf/material.rs:197

/// * `textures`: A slice containing a [TextureResource] for every texture defined in the document, in that order, so that
/// a texture can be looked up using the index of a texture within the document. Materials in glTF specify their target
/// textures by their index within the node list of the document, and these indices need to be translated into handles.
///
/// * `buffers`: A slice containing a list of byte-vectors, one for each buffer in the glTF document.
/// Animations in glTF make reference to data stored in the document's list of buffers by index.
/// This slcie allows an index into the document's list of buffers to be translated into actual bytes of data.
///
/// * `resource_manager`: A [ResourceManager] makes it possible to access shaders and create materials.
pub async fn import_materials(
    gltf: &Document,
    textures: &[TextureResource],
) -> Result<Vec<MaterialResource>> {
    let mut result: Vec<MaterialResource> = Vec::with_capacity(gltf.materials().len());
    for mat in gltf.materials() {
        match import_material(mat, textures).await {
            Ok(res) => result.push(res),
            Err(err) => {
                Log::err(format!("glTF material failed to import. Reason: {err:?}"));
                result.push(MaterialResource::new_ok(
                    Uuid::new_v4(),
                    ResourceKind::Embedded,
                    Material::default(),
                ));
            }
        }
    }
    Ok(result)
}

async fn import_material(
    mat: gltf::Material<'_>,
    textures: &[TextureResource],
) -> Result<MaterialResource> {
    let shader: ShaderResource = GLTF_SHADER.resource.clone();
    if !shader.is_ok() {
        return Err(GltfMaterialError::ShaderLoadFailed);

View on GitHub (pinned to 76c91aad8e)