phaserjs/phaser · error · Error
Color attachments must have the same dimensions
Error message
Color attachments must have the same dimensions
What it means
Thrown by WebGLFramebufferWrapper when creating a framebuffer with multiple color attachments where attachment[i] (i>0) has a width or height different from attachment[0]. WebGL MRT (multiple render targets) requires all color attachments to be the same dimensions, so the wrapper rejects mismatched inputs at construction.
Source
Thrown at src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js:142
this.attachments = [];
if (!this.useCanvas)
{
for (var i = 0; i < colorAttachments.length; i++)
{
this.attachments.push({
texture: colorAttachments[i],
attachmentPoint: gl.COLOR_ATTACHMENT0 + i
});
if (i === 0)
{
this.width = colorAttachments[i].width;
this.height = colorAttachments[i].height;
}
else if (colorAttachments[i].width !== this.width || colorAttachments[i].height !== this.height)
{
throw new Error('Color attachments must have the same dimensions');
}
}
// Only generate depth and stencil buffers if color attachments are provided.
// Generate a depth-stencil buffer if both are requested.
// These must be attached after the color attachments,
// so that the framebuffer is complete when they're attached.
if (addDepthBuffer && addStencilBuffer)
{
this.attachments.push({
attachmentPoint: gl.DEPTH_STENCIL_ATTACHMENT,
internalFormat: gl.DEPTH_STENCIL
});
}
else if (addDepthBuffer)
{
this.attachments.push({
attachmentPoint: gl.DEPTH_ATTACHMENT,View on GitHub (pinned to 41be1e462b)
Solutions
- Ensure all color attachments are created with identical width and height.
- Recreate/resize every attachment together on canvas resize before rebuilding the framebuffer.
- Allocate targets from a shared size constant.
- If different sizes are genuinely needed, use separate framebuffers and composite, not MRT.
Example fix
// before
new WebGLFramebufferWrapper(renderer, {
colorAttachments: [texA, texB] // texA 1024x768, texB 512x512 -> throws
});
// after
const w = 1024, h = 768;
texB = renderer.createTexture(w, h);
new WebGLFramebufferWrapper(renderer, { colorAttachments: [texA, texB] }); Defensive patterns
Strategy: validation
Validate before calling
const w0 = colorAttachments[0].width, h0 = colorAttachments[0].height;
if (!colorAttachments.every(t => t.width === w0 && t.height === h0)) {
throw new Error('Color attachments differ in size');
} Type guard
function attachmentsSameSize(atts) {
if (!atts.length) return true;
const { width, height } = atts[0];
return atts.every(t => t.width === width && t.height === height);
} Prevention
- Allocate all attachments from one shared (w,h).
- Recreate every attachment on canvas resize.
- Keep MRT targets in a single descriptor object.
When it happens
Trigger: Constructing a WebGLFramebufferWrapper with a colorAttachments array whose textures have differing .width/.height; passing a render texture and a game texture of different sizes; resizing one attachment but not the others before rebuilding the framebuffer.
Common situations: Custom multi-target render passes (e.g. G-buffer with position + normals + albedo) where textures were allocated at different sizes; compositing pipelines that mix a half-res and full-res target into one framebuffer; post-process chains where one buffer was resized on canvas resize and another was not.
Related errors
- Framebuffer status:
- Invalid buffer type for ARRAY_BUFFER
- Invalid buffer type for ELEMENT_ARRAY_BUFFER
- BatchHandler must have a name
- BatchHandlerStrip: Vertex count exceeds maximum per batch (
AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13).
Data as JSON: /api/errors/4c1e8c3db0a24072.
Report an issue: GitHub.