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

  1. Ensure the shadow generator's light is a DirectionalLight before constructing the mesh, or create a new ShadowGenerator bound to a DirectionalLight.
  2. Pass no shadowGenerator argument if you do not need shadow coupling, then set up lighting separately.
  3. 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

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


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