mrdoob/three.js · error · Error
THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge
Error message
THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.
What it means
Thrown by readRenderTargetPixelsAsync when the target texture's type is not GPU-readable for pixel readback. Readability is determined by capabilities.textureTypeReadable(type); types outside UnsignedByteType (and implementation-defined readable types) cannot be read. This commonly hits floating-point (HalfFloat/Float) targets when the EXT_color_buffer_float / read-on-float extension is unavailable.
Source
Thrown at src/renderers/WebGLRenderer.js:3223
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 );
// check if the commands have finished every 8 ms
const sync = _gl.fenceSync( _gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
_gl.flush();
View on GitHub (pinned to da05705fa3)
Solutions
- Use UnsignedByteType for targets you read back via this method, or confirm the context supports float readback (renderer.capabilities) before using FloatType/HalfFloatType.
- Render float results into an RGBA8/UnsignedByte target (encoding the values) and read that back instead.
- Request a context that exposes EXT_color_buffer_float / OES_texture_float and verify before relying on float readback.
- Downgrade the readback target type to UnsignedByteType as a portable fallback.
Example fix
// before
const rt = new THREE.WebGLRenderTarget( w, h, { type: THREE.FloatType } );
await renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf ); // throws without float read
// after
const rt = new THREE.WebGLRenderTarget( w, h ); // UnsignedByteType default
await renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf ); Defensive patterns
Strategy: validation
Validate before calling
const readable = renderer.capabilities && renderer.capabilities.textureTypeReadable
? renderer.capabilities.textureTypeReadable( renderTarget.texture.type )
: ( renderTarget.texture.type === THREE.UnsignedByteType );
if ( readable ) {
await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );
} Prevention
- Use UnsignedByteType for readback targets unless float-read is confirmed.
- Verify float/half-float readback support via capabilities before using FloatType/HalfFloatType.
- Encode float results into an RGBA8 target for portable readback.
- Request a context exposing float-read extensions and verify before relying on them.
When it happens
Trigger: Creating a WebGLRenderTarget with texture.type = HalfFloatType or FloatType, then readRenderTargetPixelsAsync, on a context that lacks float-readback support.
Common situations: HDR/compute-style pipelines that render to float targets for readback; mobile/Safari contexts without float-read extensions; reading back picking/GPU-compute results stored in float buffers.
Related errors
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge
- THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested r
- THREE.TextureUtils: Unknown texture type ${type}.
- THREE.WebGLRenderer: WebGL 1 is not supported since r163.
AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12).
Data as JSON: /api/errors/8dc235bf6fc43974.
Report an issue: GitHub.