BabylonJS/Babylon.js · error

Unable to create dummy framebuffer

Error message

Unable to create dummy framebuffer

What it means

readTexture uses a lazily-created dummy framebuffer (_dummyFramebuffer) to perform GPU-side pixel reads. If gl.createFramebuffer() returns null when first allocating this helper, this error is thrown. Like the other framebuffer errors, it points to driver/context-level allocation failure, not a usage error.

Source

Thrown at packages/dev/core/src/Engines/Extensions/engine.readTexture.pure.ts:42

        width: number,
        height: number,
        faceIndex = -1,
        level = 0,
        buffer: Nullable<ArrayBufferView> = null,
        flushRenderer = true,
        noDataConversion = false,
        x = 0,
        y = 0
    ): ArrayBufferView {
        const gl = this._gl;
        if (!gl) {
            throw new Error("Engine does not have gl rendering context.");
        }
        if (!this._dummyFramebuffer) {
            const dummy = gl.createFramebuffer();

            if (!dummy) {
                throw new Error("Unable to create dummy framebuffer");
            }

            this._dummyFramebuffer = dummy;
        }
        gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);

        if (faceIndex > -1 && (texture.is2DArray || texture.is3D)) {
            gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture._hardwareTexture?.underlyingResource, level, faceIndex);
        } else if (faceIndex > -1) {
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._hardwareTexture?.underlyingResource, level);
        } else {
            gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._hardwareTexture?.underlyingResource, level);
        }

        let readType = texture.type !== undefined ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;

        if (!noDataConversion) {
            switch (readType) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Verify context is alive (listen for webglcontextlost) and re-create engine if lost
  2. Retry the readPixels call after context restore
  3. Reduce GPU memory pressure (dispose unused textures/render targets)
  4. Update GPU drivers/browser
  5. Catch and fall back to reading pixels without the GPU path (e.g. sync texture data with noDataConversion/data source)

Example fix

// before
const data = engine.readPixels(texture);
// after
try {
  const data = engine.readPixels(texture);
} catch (e) {
  // fall back: read from CPU-side texture buffer if available
  const data = texture._bufferSource;
}
Defensive patterns

Strategy: try-catch

Validate before calling

function canReadTexture(engine) {
  return !engine.isDisposed && !!(engine as any)._gl;
}

Type guard

function hasGlContext(engine): boolean {
  return !engine.isDisposed && !!(engine as any)._gl;
}

Try / catch

let data: ArrayBufferView | null = null;
try {
  data = engine.readPixels(texture);
} catch (e) {
  if (String(e?.message).includes('dummy framebuffer')) {
    data = texture._bufferSource ?? null; // CPU-side fallback
  } else { throw e; }
}

Prevention

When it happens

Trigger: First call to engine.readPixels/readTexture when gl.createFramebuffer() for the dummy framebuffer returns null — context lost, driver exhaustion, or non-compliant GL implementation.

Common situations: Context loss between engine creation and the first readPixels call; mobile devices under memory pressure; browsers with many live WebGL contexts; buggy drivers returning null from createFramebuffer.

Related errors


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