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
- Recreate the depth texture with the same samples value as the target texture (or vice versa).
- Read the target texture's description (frameGraph.textureManager.getTextureDescription) and match depthTexture creation options.samples to it.
- 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
- Always create depth textures with samples copied from the target texture description.
- Centralize MSAA sample count in one constant used by every texture creation.
- Check back-buffer samples (can be device-dependent) before assuming samples:1.
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
- FrameGraphMotionBlurTask "${this.name}": depthTexture is req
- ${className} ${this.name}: the back buffer depth/stencil tex
- ${className} ${this.name}: the depth texture (size: ${depthT
- FrameGraphClearTextureTask ${this.name}: the depth texture (
- FrameGraphHighlightLayerTask "${this.name}": objectRendererT
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/5b38a66670b1fc10.
Report an issue: GitHub.