BabylonJS/Babylon.js · error
Unable to create multi sampled framebuffer
Error message
Unable to create multi sampled framebuffer
What it means
When creating/updating a render target wrapper with samples > 1 (and WebGL2 renderbufferStorageMultisample available), the engine allocates an MSAA framebuffer via gl.createFramebuffer(). A null return triggers this error. It indicates the driver could not create the framebuffer object for the render target's MSAA resolve path.
Source
Thrown at packages/dev/core/src/Engines/Extensions/engine.renderTarget.pure.ts:222
// Dispose previous render buffers
if (rtWrapper._depthStencilBuffer) {
gl.deleteRenderbuffer(rtWrapper._depthStencilBuffer);
rtWrapper._depthStencilBuffer = null;
}
if (rtWrapper._MSAAFramebuffer) {
gl.deleteFramebuffer(rtWrapper._MSAAFramebuffer);
rtWrapper._MSAAFramebuffer = null;
}
const hardwareTexture = rtWrapper.texture?._hardwareTexture as Nullable<WebGLHardwareTexture>;
hardwareTexture?.releaseMSAARenderBuffers();
if (rtWrapper.texture && samples > 1 && typeof gl.renderbufferStorageMultisample === "function") {
const framebuffer = gl.createFramebuffer();
if (!framebuffer) {
throw new Error("Unable to create multi sampled framebuffer");
}
rtWrapper._MSAAFramebuffer = framebuffer;
this._bindUnboundFramebuffer(rtWrapper._MSAAFramebuffer);
const colorRenderbuffer = this._createRenderBuffer(
rtWrapper.texture.width,
rtWrapper.texture.height,
samples,
-1 /* not used */,
this._getRGBABufferInternalSizedFormat(rtWrapper.texture.type, rtWrapper.texture.format, rtWrapper.texture._useSRGBBuffer),
gl.COLOR_ATTACHMENT0,
false
);
if (!colorRenderbuffer) {
throw new Error("Unable to create multi sampled framebuffer");
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Lower samples (2 or 1) on the render target
- Check for and recover from context loss (webglcontextlost/webglcontextrestored)
- Dispose unused render targets to free framebuffer objects
- Update GPU drivers; verify on other hardware
- Try-catch creation and rebuild the render target without MSAA
Example fix
// before
const rt = engine.createRenderTargetTexture(size, { samples: 4 });
// after
let rt;
try {
rt = engine.createRenderTargetTexture(size, { samples: 4 });
} catch {
rt = engine.createRenderTargetTexture(size, {}); // no MSAA
} Defensive patterns
Strategy: try-catch
Validate before calling
function msaaSupported(engine, samples) {
const gl = engine._gl;
if (!gl || typeof gl.renderbufferStorageMultisample !== 'function') return false;
return samples <= gl.getParameter(gl.MAX_SAMPLES);
} Type guard
function hasLiveContext(engine): boolean {
return !engine.isDisposed && !!(engine as any)._gl;
} Try / catch
try {
const rt = engine.createRenderTargetTexture(size, { samples: 4 });
} catch (e) {
if (String(e?.message).includes('multi sampled framebuffer')) {
const rt = engine.createRenderTargetTexture(size, {}); // MSAA off
} else { throw e; }
} Prevention
- Clamp samples to gl.MAX_SAMPLES
- Recover render targets after context restore
- Dispose stale render targets to avoid framebuffer exhaustion
- Avoid repeated resize churn on MSAA targets
- Validate MSAA on target hardware early
When it happens
Trigger: engine.createRenderTargetTexture / RenderTargetTexture creation or resize with samples > 1 where gl.createFramebuffer() returns null (context loss, resource exhaustion).
Common situations: MSAA render targets (samples=4) created at startup on constrained GPUs; resizing render targets repeatedly leaking framebuffers; context lost mid-frame; old drivers with framebuffer allocation bugs.
Related errors
- Unable to create multi sampled framebuffer
- Unable to create dummy framebuffer
- updateWrappedWebGLTexture: wrapped texture is part of a mult
- updateWrappedWebGLTexture: wrapped texture's render-target w
- Atmosphere is not supported on WebGL ${engine.version}.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/e5fca4c5741e26a1.
Report an issue: GitHub.