BabylonJS/Babylon.js · error · Error
FrameGraphSSAO2Task "${this.name}": sourceTexture, depthText
Error message
FrameGraphSSAO2Task "${this.name}": sourceTexture, depthTexture, normalTexture and camera are required What it means
FrameGraphSSAO2Task.record() validates that all required inputs were assigned before the frame graph is built. The SSAO2 post-process needs the source (color) texture, depth texture, normal texture and a camera to configure its rendering passes; if any is undefined the task cannot be recorded, so the library throws immediately instead of failing later with a confusing GPU/effect error. This is a fail-fast precondition check inside Babylon.js' frame graph system.
Source
Thrown at packages/dev/core/src/FrameGraph/Tasks/PostProcesses/ssao2Task.ts:30
public normalTexture: FrameGraphTextureHandle;
public camera: Camera;
public override readonly postProcess: ThinSSAO2PostProcess;
private _currentCameraMode = -1;
constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinSSAO2PostProcess) {
super(name, frameGraph, thinPostProcess || new ThinSSAO2PostProcess(name, frameGraph.scene));
}
public override getClassName(): string {
return "FrameGraphSSAO2Task";
}
public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {
if (this.sourceTexture === undefined || this.depthTexture === undefined || this.normalTexture === undefined || this.camera === undefined) {
throw new Error(`FrameGraphSSAO2Task "${this.name}": sourceTexture, depthTexture, normalTexture and camera are required`);
}
this._currentCameraMode = this.camera.mode;
this.postProcess.updateEffect();
const pass = super.record(
skipCreationOfDisabledPasses,
(context) => {
this.postProcess.camera = this.camera;
if (this._currentCameraMode !== this.camera.mode) {
this._currentCameraMode = this.camera.mode;
this.postProcess.updateEffect();
}
context.setTextureSamplingMode(this.depthTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);
context.setTextureSamplingMode(this.normalTexture, Constants.TEXTURE_BILINEAR_SAMPLINGMODE);
},
View on GitHub (pinned to 0592b347b8)
Solutions
- Assign sourceTexture, depthTexture and normalTexture from the frame graph texture manager / producing task outputs before building: task.sourceTexture = ...; task.depthTexture = ...; task.normalTexture = ...;
- Set task.camera to a valid Camera (e.g. frameGraph.scene.activeCamera) before record()/build()
- Ensure the tasks producing the depth/normal textures are added to the graph BEFORE the SSAO2 task and their outputs linked to these inputs
- Wrap the build call in try/catch and log which of the four inputs is undefined to pinpoint the missing one
Example fix
// before
const ssao2Task = new FrameGraphSSAO2Task("ssao2", frameGraph, { samples: 16 });
frameGraph.addTask(ssao2Task);
frameGraph.build(); // throws: inputs undefined
// after
const ssao2Task = new FrameGraphSSAO2Task("ssao2", frameGraph, { samples: 16 });
ssao2Task.sourceTexture = mainTextureTask.outputTexture;
ssao2Task.depthTexture = depthTextureTask.outputTexture;
ssao2Task.normalTexture = normalTextureTask.outputTexture;
ssao2Task.camera = frameGraph.scene.activeCamera;
frameGraph.addTask(ssao2Task);
frameGraph.build(); Defensive patterns
Strategy: validation
Validate before calling
// before frameGraph.build()
const required = { sourceTexture: ssao2Task.sourceTexture, depthTexture: ssao2Task.depthTexture, normalTexture: ssao2Task.normalTexture, camera: ssao2Task.camera };
const missing = Object.entries(required).filter(([, v]) => v === undefined).map(([k]) => k);
if (missing.length) throw new Error(`SSAO2 task missing inputs: ${missing.join(", ")}`); Type guard
function hasSSAO2Inputs(t) { return t.sourceTexture !== undefined && t.depthTexture !== undefined && t.normalTexture !== undefined && t.camera !== undefined; } Try / catch
try { frameGraph.build(); } catch (e) { if (String(e.message).includes("sourceTexture, depthTexture, normalTexture and camera are required")) { console.error("SSAO2 task inputs not wired:", { source: ssao2Task.sourceTexture, depth: ssao2Task.depthTexture, normal: ssao2Task.normalTexture, camera: ssao2Task.camera }); } else { throw e; } } Prevention
- Assign all task input properties immediately after constructing the task, before adding it to the graph
- Add tasks to the graph in dependency order (producers before consumers)
- Keep a small setup helper that wires every post-process task's inputs in one place
- Assert required inputs before calling frameGraph.build() in debug builds
When it happens
Trigger: Calling FrameGraphSSAO2Task.record() (directly or via FrameGraph.build()) when sourceTexture, depthTexture, normalTexture or camera was never set on the task instance, e.g. the task was added to the graph but its input properties were never assigned from texture manager handles or a camera.
Common situations: Building a frame graph where the SSAO2 task was wired before the source pipeline task produced its texture handles; forgetting to pass the camera when constructing the task; refactoring away from the legacy SSAO2RenderingPipeline where the pipeline grabbed scene textures automatically — frame graph tasks require explicit texture bindings; conditional code paths that skip texture assignment.
Related errors
- FrameGraphAnaglyphTask "${this.name}": sourceTexture and lef
- FrameGraphBloomMergeTask "${this.name}": sourceTexture and b
- FrameGraphBloomTask: sourceTexture is required
- FrameGraphCircleOfConfusionTask "${this.name}": sourceTextur
- FrameGraphPostProcessTask "${this.name}": sourceTexture or t
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/ab03c0dfd35aba17.
Report an issue: GitHub.