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
- Import the glTF loader module that registers the PBR implementation (e.g. '@babylonjs/loaders/glTF/2.0' side-effect import) before loading assets.
- Check that your bundler does not tree-shake the registration import (keep it for its side effects).
- Verify PBRMaterial and its factory code are included in the bundle.
- 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
- Always import the full loaders/glTF/2.0 entry point (side-effect import) in modular setups.
- Mark loader registration imports as side-effectful so bundlers keep them.
- Smoke-test asset loading in CI to catch missing registrations early.
- Register implementations before any async load call, not inside render callbacks.
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
- ${extraContext}: Material type not supported
- Appropriate material adapter class not found
- The loader plugin corresponding to the '${pluginExtension}'
- HDR prefiltering is not available in WebGL 1., you can use r
- Import MeshBuilder to populate this function
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/800958e3fa41604e.
Report an issue: GitHub.