{"record":{"id":"8dc235bf6fc43974","repo":"mrdoob/three.js","slug":"three-webglrenderer-readrendertargetpixelsasync-r-8dc235","errorCode":null,"errorMessage":"THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.","messagePattern":"THREE\\.WebGLRenderer\\.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderers/WebGLRenderer.js","lineNumber":3223,"sourceCode":"\t\t\t\t\tconst texture = renderTarget.textures[ textureIndex ];\n\t\t\t\t\tconst textureFormat = texture.format;\n\t\t\t\t\tconst textureType = texture.type;\n\n\t\t\t\t\t// when using MRT, select the correct color buffer for the subsequent read command\n\n\t\t\t\t\tif ( renderTarget.textures.length > 1 ) _gl.readBuffer( _gl.COLOR_ATTACHMENT0 + textureIndex );\n\n\t\t\t\t\tconst readableState = getReadableState( texture );\n\n\t\t\t\t\tif ( readableState.__formatReadable === false ) {\n\n\t\t\t\t\t\tthrow new Error( 'THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( readableState.__typeReadable === false ) {\n\n\t\t\t\t\t\tthrow new Error( 'THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t\tconst glBuffer = _gl.createBuffer();\n\t\t\t\t\t_gl.bindBuffer( _gl.PIXEL_PACK_BUFFER, glBuffer );\n\t\t\t\t\t_gl.bufferData( _gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ );\n\n\t\t\t\t\t_gl.readPixels( x, y, width, height, utils.convert( textureFormat ), utils.convert( textureType ), 0 );\n\n\t\t\t\t\t// reset the frame buffer to the currently set buffer before waiting\n\t\t\t\t\tconst currFramebuffer = _currentRenderTarget !== null ? properties.get( _currentRenderTarget ).__webglFramebuffer : null;\n\t\t\t\t\tstate.bindFramebuffer( _gl.FRAMEBUFFER, currFramebuffer );\n\n\t\t\t\t\t// check if the commands have finished every 8 ms\n\t\t\t\t\tconst sync = _gl.fenceSync( _gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );\n\n\t\t\t\t\t_gl.flush();\n","sourceCodeStart":3205,"sourceCodeEnd":3241,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/renderers/WebGLRenderer.js#L3205-L3241","documentation":"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.","triggerScenarios":"Creating a WebGLRenderTarget with texture.type = HalfFloatType or FloatType, then readRenderTargetPixelsAsync, on a context that lacks float-readback support.","commonSituations":"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.","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."],"exampleFix":"// before\nconst rt = new THREE.WebGLRenderTarget( w, h, { type: THREE.FloatType } );\nawait renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf ); // throws without float read\n\n// after\nconst rt = new THREE.WebGLRenderTarget( w, h ); // UnsignedByteType default\nawait renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf );","handlingStrategy":"validation","validationCode":"const readable = renderer.capabilities && renderer.capabilities.textureTypeReadable\n  ? renderer.capabilities.textureTypeReadable( renderTarget.texture.type )\n  : ( renderTarget.texture.type === THREE.UnsignedByteType );\nif ( readable ) {\n  await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["webglrenderer","readback","texture-type","float","capabilities"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}