BabylonJS/Babylon.js · error
LightingVolumeMesh ${name}: light must be a directional ligh
Error message
LightingVolumeMesh ${name}: light must be a directional light What it means
LightingVolumeMesh is a helper mesh built around a ShadowGenerator, and its internal volumetric lighting math only works with a directional light. In the constructor, if a ShadowGenerator is passed whose light is not an instance of DirectionalLight, the constructor throws immediately before building any geometry.
Source
Thrown at packages/dev/core/src/Lights/lightingVolume.pure.ts:153
}
if (this._cs2) {
this._cs2.fastMode = enabled;
this._cs2.triggerContextRebuild = enabled;
}
}
/**
* Creates a new LightingVolume.
* @param name The name of the lighting volume.
* @param scene The scene the lighting volume belongs to.
* @param shadowGenerator The shadow generator used to create the lighting volume. This is optional in the constructor, but must be set before calling updateMesh.
* @param tesselation The tesselation level of the lighting volume (default: 64).
*/
constructor(name: string, scene: Scene, shadowGenerator?: ShadowGenerator, tesselation = 64) {
const light = shadowGenerator ? shadowGenerator.getLight() : undefined;
if (light && !(light instanceof DirectionalLight)) {
throw new Error(`LightingVolumeMesh ${name}: light must be a directional light`);
}
this._name = name;
this._shadowGenerator = shadowGenerator;
this._light = light as DirectionalLight;
this._indices = [];
this._engine = scene.getEngine();
this._scene = scene;
this._mesh = new Mesh(name, this._scene);
scene.meshes.splice(scene.meshes.indexOf(this._mesh), 1);
if (this._engine.isWebGPU) {
this._uBuffer = new UniformBuffer(this._engine);
this._uBuffer.addUniform("invViewProjMatrix", 16);
this._uBuffer.addUniform("invViewMatrix", 16);
View on GitHub (pinned to 0592b347b8)
Solutions
- Ensure the shadow generator's light is a DirectionalLight before constructing the mesh, or create a new ShadowGenerator bound to a DirectionalLight.
- Pass no shadowGenerator argument if you do not need shadow coupling, then set up lighting separately.
- Replace the scene's SpotLight/PointLight with a DirectionalLight if directional shadows are acceptable.
Example fix
// before
const spot = new BABYLON.SpotLight("spot", pos, dir, 1.2, 10, scene);
const sg = new BABYLON.ShadowGenerator(1024, spot);
const vol = new BABYLON.LightingVolumeMesh("vol", scene, sg); // throws
// after
const dir = new BABYLON.DirectionalLight("dir", new BABYLON.Vector3(-1, -2, -1), scene);
const sg = new BABYLON.ShadowGenerator(1024, dir);
const vol = new BABYLON.LightingVolumeMesh("vol", scene, sg); Defensive patterns
Strategy: validation
Validate before calling
const light = shadowGenerator?.getLight();
if (light && !(light instanceof BABYLON.DirectionalLight)) {
throw new Error("LightingVolumeMesh requires a directional light");
} Type guard
function isDirectionalLight(light: BABYLON.Light | undefined): light is BABYLON.DirectionalLight {
return !!light && (light as BABYLON.DirectionalLight).getDirection !== undefined && light instanceof BABYLON.DirectionalLight;
} Try / catch
try {
const vol = new BABYLON.LightingVolumeMesh(name, scene, sg);
} catch (e) {
if ((e as Error).message.includes("directional light")) {
console.warn("Falling back: shadow generator light is not directional", e);
}
} Prevention
- Always bind ShadowGenerator to a DirectionalLight when lighting volumes are involved.
- Add an instanceof DirectionalLight assertion in scene setup code.
- Keep light creation and generator creation adjacent so types are visible at the call site.
When it happens
Trigger: new LightingVolumeMesh(name, scene, shadowGenerator) where shadowGenerator.getLight() returns a light that is not a DirectionalLight (e.g. a SpotLight or PointLight was assigned to the generator).
Common situations: Attaching a LightingVolumeMesh to an existing ShadowGenerator that was created for a spot or point light; refactoring scene lighting from spot to directional without updating the volume; copying sample code while keeping a different light type.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- FrameGraphLightingVolumeTask ${this.name}: light must be a d
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
- At least one mesh is needed to create the nav mesh.
- At least one mesh is needed to create the nav mesh.
- Unable to create navmesh. No navMesh or navMeshQuery returne
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/629453dd5eccde87.
Report an issue: GitHub.