BabylonJS/Babylon.js · error · Error

FrameGraphBloomMergeTask "${this.name}": sourceTexture, circ

Error message

FrameGraphBloomMergeTask "${this.name}": sourceTexture, circleOfConfusionTexture and blurSteps are required

What it means

FrameGraphDepthOfFieldMergeTask.record() requires sourceTexture, circleOfConfusionTexture, and at least one blur step before it can merge the blurred mip chain back over the source. It throws when any of the three is missing (empty blurSteps array counts as missing). The message text says "FrameGraphBloomMergeTask", a known copy-paste typo in the source, but the check belongs to the DoF merge task.

Source

Thrown at packages/dev/core/src/FrameGraph/Tasks/PostProcesses/depthOfFieldMergeTask.ts:24

/**
 * @internal
 */
export class FrameGraphDepthOfFieldMergeTask extends FrameGraphPostProcessTask {
    public circleOfConfusionTexture: FrameGraphTextureHandle;

    public blurSteps: FrameGraphTextureHandle[] = [];

    constructor(name: string, frameGraph: FrameGraph, thinPostProcess?: ThinDepthOfFieldMergePostProcess) {
        super(name, frameGraph, thinPostProcess || new ThinDepthOfFieldMergePostProcess(name, frameGraph.engine));
    }

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

    public override record(skipCreationOfDisabledPasses = false): FrameGraphRenderPass {
        if (this.sourceTexture === undefined || this.circleOfConfusionTexture === undefined || this.blurSteps.length === 0) {
            throw new Error(`FrameGraphBloomMergeTask "${this.name}": sourceTexture, circleOfConfusionTexture and blurSteps are required`);
        }

        this.postProcess.updateEffect("#define BLUR_LEVEL " + (this.blurSteps.length - 1) + "\n");

        const pass = super.record(
            skipCreationOfDisabledPasses,
            (context) => {
                context.setTextureSamplingMode(this.blurSteps[this.blurSteps.length - 1], Constants.TEXTURE_BILINEAR_SAMPLINGMODE);
            },
            (context) => {
                context.bindTextureHandle(this._postProcessDrawWrapper.effect!, "circleOfConfusionSampler", this.circleOfConfusionTexture);
                for (let i = 0; i < this.blurSteps.length; i++) {
                    const handle = this.blurSteps[i];
                    context.bindTextureHandle(this._postProcessDrawWrapper.effect!, "blurStep" + (this.blurSteps.length - i - 1), handle);
                }
            }
        );

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Assign task.sourceTexture to the scene/color texture handle.
  2. Assign task.circleOfConfusionTexture to the CoC task output.
  3. Populate task.blurSteps with outputs from the DoF blur tasks (at least one entry).
  4. Ignore the "BloomMergeTask" wording in the message; it is a typo — this is the depth-of-field merge task.

Example fix

// before
const merge = new FrameGraphDepthOfFieldMergeTask(frameGraph, "dofMerge");
frameGraph.addTask(merge);

// after
const merge = new FrameGraphDepthOfFieldMergeTask(frameGraph, "dofMerge");
merge.sourceTexture = sourceTask.outputTexture;
merge.circleOfConfusionTexture = cocTask.outputTexture;
merge.blurSteps = [blurNear.outputTexture, blurFar.outputTexture];
frameGraph.addTask(merge);
Defensive patterns

Strategy: validation

Validate before calling

if (mergeTask.sourceTexture === undefined || mergeTask.circleOfConfusionTexture === undefined || mergeTask.blurSteps.length === 0) {
  throw new Error("DoF merge task missing source/CoC textures or blurSteps before build");
}

Type guard

function hasDoFMergeInputs(t: { sourceTexture?: unknown; circleOfConfusionTexture?: unknown; blurSteps: unknown[] }): boolean {
  return t.sourceTexture !== undefined && t.circleOfConfusionTexture !== undefined && t.blurSteps.length > 0;
}

Try / catch

try {
  frameGraph.build();
} catch (e) {
  if (String(e?.message).includes("blurSteps are required")) {
    console.error("DoF merge task not wired (note: message says BloomMerge due to a typo):", e.message);
  } else { throw e; }
}

Prevention

When it happens

Trigger: Recording a DoF merge task with unassigned sourceTexture or circleOfConfusionTexture handles, or without having recorded/added any FrameGraphDepthOfFieldBlurTask outputs into task.blurSteps.

Common situations: Setting up depth of field manually and forgetting to feed the blur chain; configuring only the near-field or far-field half of DoF; a misleading "BloomMerge" error message sending developers to search bloom code instead of DoF code.

Related errors


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