{"record":{"id":"f452f0af1558e7f0","repo":"mrdoob/three.js","slug":"three-webglrenderer-readrendertargetpixelsasync-r","errorCode":null,"errorMessage":"THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.","messagePattern":"THREE\\.WebGLRenderer\\.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderers/WebGLRenderer.js","lineNumber":3217,"sourceCode":"\t\t\t\t// the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)\n\t\t\t\tif ( ( x >= 0 && x <= ( renderTarget.width - width ) ) && ( y >= 0 && y <= ( renderTarget.height - height ) ) ) {\n\n\t\t\t\t\t// set the active frame buffer to the one we want to read\n\t\t\t\t\tstate.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );\n\n\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 );","sourceCodeStart":3199,"sourceCodeEnd":3235,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/renderers/WebGLRenderer.js#L3199-L3235","documentation":"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.","triggerScenarios":"Creating a WebGLRenderTarget whose texture.format is e.g. DepthFormat, DepthStencilFormat, or a compressed/non-color format, then calling readRenderTargetPixelsAsync on it.","commonSituations":"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.","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."],"exampleFix":"// before\nconst rt = new THREE.WebGLRenderTarget( w, h );\nrt.texture.format = THREE.DepthFormat;\nawait renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf ); // throws\n\n// after\nconst rt = new THREE.WebGLRenderTarget( w, h ); // default RGBAFormat\nawait renderer.readRenderTargetPixelsAsync( rt, 0, 0, w, h, buf );","handlingStrategy":"validation","validationCode":"const readable = renderer.capabilities && renderer.capabilities.textureFormatReadable\n  ? renderer.capabilities.textureFormatReadable( renderTarget.texture.format )\n  : ( renderTarget.texture.format === THREE.RGBAFormat );\nif ( readable ) {\n  await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["webglrenderer","readback","texture-format","capabilities"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}