BabylonJS/Babylon.js · error · Error

FrameGraphScreenSpaceCurvatureTask "${this.name}": sourceTex

Error message

FrameGraphScreenSpaceCurvatureTask "${this.name}": sourceTexture and normalTexture are required

What it means

FrameGraphScreenSpaceCurvatureTask.record() requires both sourceTexture (color input) and normalTexture (the normal buffer from which curvature is derived); either being undefined aborts recording. The normal texture is additionally bound as "normalSampler" in the pass bindings.

Source

Thrown at packages/dev/core/src/FrameGraph/Tasks/PostProcesses/screenSpaceCurvatureTask.ts:33

    public override readonly postProcess: ThinScreenSpaceCurvaturePostProcess;

    /**
     * Constructs a new circle of confusion task.
     * @param name The name of the task.
     * @param frameGraph The frame graph this task belongs to.
     * @param thinPostProcess The thin post process to use for the task. If not provided, a new one will be created.
     */
    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinScreenSpaceCurvaturePostProcess) {
        super(name, frameGraph, thinPostProcess || new ThinScreenSpaceCurvaturePostProcess(name, frameGraph.engine));
    }

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

    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {
        if (this.sourceTexture === undefined || this.normalTexture === undefined) {
            throw new Error(`FrameGraphScreenSpaceCurvatureTask "${this.name}": sourceTexture and normalTexture are required`);
        }

        const pass = super.record(skipCreationOfDisabledPasses, undefined, (context) => {
            context.bindTextureHandle(this._postProcessDrawWrapper.effect!, "normalSampler", this.normalTexture);
        });

        pass.addDependencies(this.normalTexture);

        return pass;
    }
}

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Assign task.normalTexture to a normals texture handle from a normals-enabled prepass/object renderer task.
  2. Assign task.sourceTexture to the color texture handle.
  3. Ensure the normals-producing task is added to the graph before the curvature task.

Example fix

// before
const curvature = new FrameGraphScreenSpaceCurvatureTask(frameGraph, "curvature");
curvature.sourceTexture = colorTask.outputTexture;

// after
const curvature = new FrameGraphScreenSpaceCurvatureTask(frameGraph, "curvature");
curvature.sourceTexture = colorTask.outputTexture;
curvature.normalTexture = normalsPrepassTask.outputTexture;
Defensive patterns

Strategy: validation

Validate before calling

if (curvatureTask.sourceTexture === undefined || curvatureTask.normalTexture === undefined) {
  throw new Error("Curvature task missing sourceTexture/normalTexture before build");
}

Type guard

function hasCurvatureInputs(t: { sourceTexture?: unknown; normalTexture?: unknown }): boolean {
  return t.sourceTexture !== undefined && t.normalTexture !== undefined;
}

Try / catch

try {
  frameGraph.build();
} catch (e) {
  if (String(e?.message).includes("sourceTexture and normalTexture are required")) {
    console.error("Curvature task not wired:", e.message);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Adding the screen-space curvature task and building the graph without assigning task.sourceTexture or task.normalTexture (typically a normals prepass output).

Common situations: No normals prepass task in the frame graph; wiring only the color source and assuming normals are implicit; upgrading from the legacy SSAO2/curvature pipeline where normal wiring was automatic.

Related errors


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