mrdoob/three.js · error · Error
THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is
Error message
THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.
What it means
Thrown by readRenderTargetPixelsAsync when the passed renderTarget is null/undefined or lacks the isWebGLRenderTarget flag. The async variant throws (unlike the sync readRenderTargetPixels which only warns) because async pipelines expect hard failures.
Source
Thrown at src/renderers/WebGLRenderer.js:3186
*
* It is recommended to use this version of `readRenderTargetPixels()` whenever possible.
*
* @async
* @param {WebGLRenderTarget} renderTarget - The render target to read from.
* @param {number} x - The `x` coordinate of the copy region's origin.
* @param {number} y - The `y` coordinate of the copy region's origin.
* @param {number} width - The width of the copy region.
* @param {number} height - The height of the copy region.
* @param {TypedArray} buffer - The result buffer.
* @param {number} [activeCubeFaceIndex] - The active cube face index.
* @param {number} [textureIndex=0] - The texture index of an MRT render target.
* @return {Promise<TypedArray>} A Promise that resolves when the read has been finished. The resolve provides the read data as a typed array.
*/
this.readRenderTargetPixelsAsync = async function ( renderTarget, x, y, width, height, buffer, activeCubeFaceIndex, textureIndex = 0 ) {
if ( ! ( renderTarget && renderTarget.isWebGLRenderTarget ) ) {
throw new Error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
}
let framebuffer = properties.get( renderTarget ).__webglFramebuffer;
if ( renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined ) {
framebuffer = framebuffer[ activeCubeFaceIndex ];
}
if ( framebuffer ) {
// 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 );
View on GitHub (pinned to da05705fa3)
Solutions
- Ensure the argument is a WebGLRenderTarget (or WebGLCubeRenderTarget, which extends it) before calling.
- Guard: if (renderTarget && renderTarget.isWebGLRenderTarget) { ... } around the call.
- For cube render targets, pass the correct activeCubeFaceIndex and confirm isWebGLCubeRenderTarget if needed.
- Check that the render target was created with new THREE.WebGLRenderTarget(...) and not disposed.
Example fix
// before
const data = await renderer.readRenderTargetPixelsAsync( someTexture, 0, 0, w, h, buf ); // not a RT
// after
if ( renderTarget && renderTarget.isWebGLRenderTarget ) {
const data = await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );
} Defensive patterns
Strategy: type-guard
Validate before calling
if ( renderTarget && renderTarget.isWebGLRenderTarget ) {
const data = await renderer.readRenderTargetPixelsAsync( renderTarget, 0, 0, w, h, buf );
} Type guard
function isWebGLRenderTarget( obj ) {
return obj != null && obj.isWebGLRenderTarget === true;
} Prevention
- Always check renderTarget.isWebGLRenderTarget before the async read.
- Pass a WebGLRenderTarget (or WebGLCubeRenderTarget) instance only.
- Handle null/undefined returns from upstream functions before reading.
- Remember the async variant throws where the sync one only warns.
When it happens
Trigger: Passing a regular Texture, a canvas, null, a WebGLCubeRenderTarget used incorrectly, or any object that is not a WebGLRenderTarget to readRenderTargetPixelsAsync.
Common situations: Refactoring from readRenderTargetPixels (sync) to the async variant and passing the same unguarded arguments; passing a texture instead of its owning render target; passing the result of a function that may return null.
Related errors
- THREE.WebGLRenderer: Attached DepthTexture is initialized to
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarge
- THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested r
- 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/0b53db8be154673f.
Report an issue: GitHub.