BabylonJS/Babylon.js · error · Error

No PBR material implementation loaded

Error message

No PBR material implementation loaded

What it means

The glTF loader delegates PBR material creation to a pluggable implementation registered in _pbrMaterialImpls (e.g. a PBRMaterial-based implementation registered by the side-effect import of the engine-specific loader module). This error means no 'pbr' implementation was registered when the loader tried to create a PBR material — the required implementation module was never loaded.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts:2392

    /**
     * Selects the appropriate PBR material implementation for a given glTF material.
     * Uses OpenPBR when the material carries a "KHR_materials_openpbr" extension or when
     * the loader-level `useOpenPBR` flag is set; falls back to standard PBR otherwise.
     * @param material The glTF material
     * @returns The matching loaded implementation
     */
    private _selectImplForGltfMaterial(material: IMaterial): Readonly<PBRMaterialImplementation> {
        if (this.parent.useOpenPBR || material.extensions?.["KHR_materials_openpbr"]) {
            const impl = this._pbrMaterialImpls.get("openpbr");
            if (impl) {
                return impl;
            }
        }
        const impl = this._pbrMaterialImpls.get("pbr");
        if (impl) {
            return impl;
        }
        throw new Error("No PBR material implementation loaded");
    }

    /**
     * Returns the default PBR material implementation used when there is no per-material
     * selection context (e.g. when creating the built-in default material for primitives
     * that have no glTF material assigned).  Prefers OpenPBR when `useOpenPBR` is set.
     * @returns The default loaded implementation
     */
    private _getDefaultImpl(): Readonly<PBRMaterialImplementation> {
        if (this.parent.useOpenPBR) {
            const impl = this._pbrMaterialImpls.get("openpbr");
            if (impl) {
                return impl;
            }
        }
        const impl = this._pbrMaterialImpls.get("pbr") ?? this._pbrMaterialImpls.values().next().value;
        if (impl) {
            return impl;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Import the glTF loader module that registers the PBR implementation (e.g. '@babylonjs/loaders/glTF/2.0' side-effect import) before loading assets.
  2. Check that your bundler does not tree-shake the registration import (keep it for its side effects).
  3. Verify PBRMaterial and its factory code are included in the bundle.
  4. Ensure the registration happens before SceneLoader.ImportAsync/LoadAsync is called.

Example fix

// before
import { GLTFLoader } from "@babylonjs/loaders/glTF/2.0/GLTFLoader"; // no impl registered
// after
import "@babylonjs/loaders/glTF/2.0"; // registers PBR material impls
import { GLTFLoader } from "@babylonjs/loaders/glTF/2.0/GLTFLoader";
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const result = await SceneLoader.ImportAsync("", "model.glb", scene);
  return result;
} catch (e) {
  if ((e as Error).message === "No PBR material implementation loaded") {
    // import the registration module and retry once
    await import("@babylonjs/loaders/glTF/2.0");
    return SceneLoader.ImportAsync("", "model.glb", scene);
  }
  throw e;
}

Prevention

When it happens

Trigger: Using the pure/tree-shaken glTFLoader entry point without importing the module that registers the PBR material implementation; a bundler tree-shaking away the registration side effect; loading materials before the implementation registry is populated.

Common situations: Migrating from the monolithic import to modular '@babylonjs/' imports and missing the glTF loader registration import; tree-shaking configurations dropping 'unused' side-effect modules; custom builds that exclude PBRMaterial.

Related errors


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