BabylonJS/Babylon.js · error

${className} ${this.name}: the depth texture "${depthTexture

Error message

${className} ${this.name}: the depth texture "${depthTextureDescription.options.labels?.[0] ?? "noname"}" (${depthTextureDescription.options.samples} samples) and the output texture "${outputTextureDescription.options.labels?.[0] ?? "noname"}" (${outputTextureDescription.options.samples} samples) must have the same number of samples

What it means

MSAA consistency check: the depth texture and the output/target texture must declare the same number of samples. Mixing a multisampled depth texture with a non-multisampled color target (or vice versa) is invalid for a render pass, so _checkTextureCompatibility throws with both textures' labels and sample counts in the message.

Source

Thrown at packages/dev/core/src/FrameGraph/Tasks/Rendering/objectRendererTask.ts:556

    }

    protected _checkTextureCompatibility(targetTextures: FrameGraphTextureHandle[]): boolean {
        const className = this.getClassName();

        let outputTextureDescription = targetTextures.length > 0 ? this._frameGraph.textureManager.getTextureDescription(targetTextures[0]) : null;
        let depthEnabled = false;

        if (this.depthTexture !== undefined) {
            if (outputTextureDescription && this.depthTexture !== backbufferDepthStencilTextureHandle && targetTextures[0] === backbufferColorTextureHandle) {
                throw new Error(`${className} ${this.name}: the back buffer depth/stencil texture is the only depth texture allowed when the target is the back buffer color`);
            }

            const depthTextureDescription = this._frameGraph.textureManager.getTextureDescription(this.depthTexture);
            if (!outputTextureDescription) {
                outputTextureDescription = depthTextureDescription;
            }
            if (depthTextureDescription.options.samples !== outputTextureDescription.options.samples) {
                throw new Error(
                    `${className} ${this.name}: the depth texture "${depthTextureDescription.options.labels?.[0] ?? "noname"}" (${depthTextureDescription.options.samples} samples) and the output texture "${outputTextureDescription.options.labels?.[0] ?? "noname"}" (${outputTextureDescription.options.samples} samples) must have the same number of samples`
                );
            }

            if (depthTextureDescription.size.width !== outputTextureDescription.size.width || depthTextureDescription.size.height !== outputTextureDescription.size.height) {
                throw new Error(
                    `${className} ${this.name}: the depth texture (size: ${depthTextureDescription.size.width}x${depthTextureDescription.size.height}) and the target texture (size: ${outputTextureDescription.size.width}x${outputTextureDescription.size.height}) must have the same dimensions.`
                );
            }

            depthEnabled = true;
        }

        this._textureWidth = outputTextureDescription?.size.width ?? 1;
        this._textureHeight = outputTextureDescription?.size.height ?? 1;

        return depthEnabled;
    }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Recreate the depth texture with the same samples value as the target texture (or vice versa).
  2. Read the target texture's description (frameGraph.textureManager.getTextureDescription) and match depthTexture creation options.samples to it.
  3. If you don't need MSAA, set samples to 1 on both textures.

Example fix

// before
const depth = frameGraph.createDepthStencilTexture('depth', { samples: 4 });
task.targetTexture = colorTexture; // samples: 1

// after
const depth = frameGraph.createDepthStencilTexture('depth', { samples: 1 }); // match target samples
task.targetTexture = colorTexture;
Defensive patterns

Strategy: validation

Validate before calling

const targetDesc = frameGraph.textureManager.getTextureDescription(targetHandle);
const depthDesc = frameGraph.textureManager.getTextureDescription(depthHandle);
if ((depthDesc.options.samples ?? 1) !== (targetDesc.options.samples ?? 1)) {
    throw new Error('Depth and target samples must match');
}

Try / catch

try {
    frameGraph.build();
} catch (e) {
    if (String(e).includes('must have the same number of samples')) {
        // recreate depth texture matching target samples, then rebuild
    } else throw e;
}

Prevention

When it happens

Trigger: task.depthTexture.options.samples differs from target texture's samples — e.g. depth created with samples=4 while targetTexture is samples=1 (or undefined samples), checked during record() via depthEnabled/_checkTextureCompatibility.

Common situations: Enabling MSAA on one resource but not the other; hardware-driven default samples on the back buffer differing from a hand-made depth texture; refactors that change samples on only one texture creation options object.

Related errors


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