BabylonJS/Babylon.js · error · Error

FrameGraphLightingVolumeTask ${this.name}: shadowGenerator i

Error message

FrameGraphLightingVolumeTask ${this.name}: shadowGenerator is required

What it means

FrameGraphLightingVolumeTask builds a lighting volume from a shadow generator, so task.shadowGenerator must be assigned before recording. The task reads shadowGenerator.light to validate and derive the light used for the volume.

Source

Thrown at packages/dev/core/src/FrameGraph/Tasks/Misc/lightingVolumeTask.ts:67

            particleSystems: [],
        };
    }

    public override isReady() {
        const isReady = this.lightingVolume.isReady();
        if (isReady) {
            this.lightingVolume._setComputeShaderFastMode(true);
        }
        return isReady;
    }

    public override getClassName(): string {
        return "FrameGraphLightingVolumeTask";
    }

    public record() {
        if (this.shadowGenerator === undefined) {
            throw new Error(`FrameGraphLightingVolumeTask ${this.name}: shadowGenerator is required`);
        }

        const light = this.shadowGenerator.light;

        if (!(light instanceof DirectionalLight)) {
            throw new Error(`FrameGraphLightingVolumeTask ${this.name}: light must be a directional light`);
        }

        this.lightingVolume.shadowGenerator = this.shadowGenerator.shadowGenerator;

        const pass = this._frameGraph.addObjectListPass(this.name);

        pass.setObjectList(this.outputMeshLightingVolume);
        pass.setExecuteFunc(() => {
            this.lightingVolume.update();
        });

        const passDisabled = this._frameGraph.addObjectListPass(this.name + "_disabled", true);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Assign task.shadowGenerator = shadowGeneratorTask.output (a FrameGraphShadowGenerator) before record().
  2. Create and record the shadow generator task before the lighting volume task in the graph.
  3. Confirm the shadow generator task actually produced output (it recorded successfully).

Example fix

// before
const lvTask = new FrameGraphLightingVolumeTask("lv", context);
context.build();
// after
const lvTask = new FrameGraphLightingVolumeTask("lv", context);
lvTask.shadowGenerator = shadowGenTask.output;
context.build();
Defensive patterns

Strategy: validation

Validate before calling

if (lightingVolumeTask.shadowGenerator === undefined) {
  throw new Error("LightingVolumeTask requires a shadowGenerator task output");
}

Type guard

function hasShadowGenerator(task: FrameGraphLightingVolumeTask): boolean {
  return task.shadowGenerator !== undefined && task.shadowGenerator.light !== undefined;
}

Try / catch

try {
  lightingVolumeTask.record();
} catch (e) {
  if (String(e).includes("shadowGenerator is required")) {
    lightingVolumeTask.shadowGenerator = shadowGenTask.output;
    lightingVolumeTask.record();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling lightingVolumeTask.record() with task.shadowGenerator undefined.

Common situations: Creating the lighting volume task before creating the shadow generator task whose output it consumes; forgetting to link the shadow generator task output to the lighting volume task; deleting a shadow generator setup during refactoring.

Related errors


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