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
- Use RGBAFormat (the default) on the render target texture you intend to read back.
- 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.
- Check renderer.capabilities / format readability before reading, and provide a readable-format intermediate target.
- 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
- Use RGBAFormat (default) for targets you intend to read back.
- Do not read back depth/depth-stencil/compressed formats via this method.
- For depth data, render depth into an RGBA intermediate and read that.
- Check format readability via capabilities before relying on readback.
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
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge
- THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested r
- THREE.WebGLRenderer: WebGL 1 is not supported since r163.
- THREE.WebGLRenderer: Error creating WebGL context with your
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/f452f0af1558e7f0.
Report an issue: GitHub.