mrdoob/three.js · error · Error

THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge

Error message

THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.

What it means

Thrown by readRenderTargetPixelsAsync when the target texture's format is not GPU-readable for pixel readback. Readability is determined by capabilities.textureFormatReadable(format); formats outside RGBA (and implementation-defined readable formats) cannot be read via readPixels.

Source

Thrown at src/renderers/WebGLRenderer.js:3217

				// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
				if ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {

					// set the active frame buffer to the one we want to read
					state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

					const texture = renderTarget.textures[ textureIndex ];
					const textureFormat = texture.format;
					const textureType = texture.type;

					// when using MRT, select the correct color buffer for the subsequent read command

					if ( renderTarget.textures.length > 1 ) _gl.readBuffer( _gl.COLOR_ATTACHMENT0 + textureIndex );

					const readableState = getReadableState( texture );

					if ( readableState.__formatReadable === false ) {

						throw new Error( 'THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.' );

					}

					if ( readableState.__typeReadable === false ) {

						throw new Error( 'THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.' );

					}

					const glBuffer = _gl.createBuffer();
					_gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, glBuffer );
					_gl.bufferData( _gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ );

					_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), 0 );

					// reset the frame buffer to the currently set buffer before waiting
					const currFramebuffer = _currentRenderTarget !== null ? properties.get( _currentRenderTarget ).__webglFramebuffer : null;
					state.bindFramebuffer( _gl.FRAMEBUFFER, currFramebuffer );

View on GitHub (pinned to da05705fa3)

Solutions

  1. Use RGBAFormat (the default) on the render target texture you intend to read back.
  2. For depth data, use a dedicated depth-reading technique (e.g. a shader that samples depthTexture into an RGBA target) rather than readRenderTargetPixelsAsync on a depth-format target.
  3. Check renderer.capabilities / format readability before reading, and provide a readable-format intermediate target.
  4. Render the data you need into an RGBA intermediate target and read that back instead.

Example fix

// before
const rt = new THREE.WebGLRenderTarget( w, h );
rt.texture.format = THREE.DepthFormat;
await renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf ); // throws

// after
const rt = new THREE.WebGLRenderTarget( w, h ); // default RGBAFormat
await renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf );
Defensive patterns

Strategy: validation

Validate before calling

const readable = renderer.capabilities && renderer.capabilities.textureFormatReadable
  ? renderer.capabilities.textureFormatReadable( renderTarget.texture.format )
  : ( renderTarget.texture.format === THREE.RGBAFormat );
if ( readable ) {
  await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );
}

Prevention

When it happens

Trigger: Creating a WebGLRenderTarget whose texture.format is e.g. DepthFormat, DepthStencilFormat, or a compressed/non-color format, then calling readRenderTargetPixelsAsync on it.

Common situations: Reading back depth/depth-stencil targets expecting raw depth data (not supported via this path); using HDR/non-RGBA color formats for readback on hardware/drivers that report them unreadable; MRT where one attachment is a non-readable format.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/f452f0af1558e7f0. Report an issue: GitHub.