mrdoob/three.js · error · Error

THREE.WebGLTextures: renderTarget.depthTexture must be an in

Error message

THREE.WebGLTextures: renderTarget.depthTexture must be an instance of THREE.DepthTexture.

What it means

Thrown by WebGLTextures.setupDepthTexture() when a render target has a depthTexture set but it is not an instance of THREE.DepthTexture (i.e. its `isDepthTexture` flag is false). WebGL FBO depth attachments require a proper DepthTexture object so the renderer can configure the depth format, attachment, and image dimensions correctly.

Source

Thrown at src/renderers/webgl/WebGLTextures.js:1763

			}

		}

		_gl.bindRenderbuffer( _gl.RENDERBUFFER, null );

	}

	// Setup resources for a Depth Texture for a FBO (needs an extension)
	function setupDepthTexture( framebuffer, renderTarget, cubeFace ) {

		const isCube = ( renderTarget.isWebGLCubeRenderTarget === true );

		state.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );

		if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {

			throw new Error( 'THREE.WebGLTextures: renderTarget.depthTexture must be an instance of THREE.DepthTexture.' );

		}

		const textureProperties = properties.get( renderTarget.depthTexture );
		textureProperties.__renderTarget = renderTarget;

		// upload an empty depth texture with framebuffer size
		if ( ! textureProperties.__webglTexture ||
				renderTarget.depthTexture.image.width !== renderTarget.width ||
				renderTarget.depthTexture.image.height !== renderTarget.height ) {

			renderTarget.depthTexture.image.width = renderTarget.width;
			renderTarget.depthTexture.image.height = renderTarget.height;
			renderTarget.depthTexture.needsUpdate = true;

		}

		if ( isCube ) {

View on GitHub (pinned to da05705fa3)

Solutions

  1. Use `new THREE.DepthTexture(width, height, type)` and assign that to renderTarget.depthTexture.
  2. If sharing depth across targets, share the same DepthTexture instance, not a generic texture.
  3. Verify with `rt.depthTexture.isDepthTexture === true` before rendering.
  4. Leave depthTexture null if you only need a depth buffer (the renderer will allocate a renderbuffer).

Example fix

// before
rt.depthTexture = new THREE.DataTexture(data, w, h); // not a DepthTexture -> throws

// after
rt.depthTexture = new THREE.DepthTexture(w, h, THREE.UnsignedIntType);
Defensive patterns

Strategy: type-guard

Validate before calling

function attachDepthTexture(rt, w, h, type = THREE.UnsignedIntType) {
  const dt = new THREE.DepthTexture(w, h, type);
  rt.depthTexture = dt;
  if (!dt.isDepthTexture) throw new Error('DepthTexture construction failed');
}

Type guard

function isDepthTexture(v) {
  return !!v && v.isDepthTexture === true;
}

Prevention

When it happens

Trigger: Assigning `renderTarget.depthTexture = someTexture` where someTexture is a regular Texture, DataTexture, or any non-DepthTexture. Reusing a render target whose depthTexture was overwritten with a generic texture.

Common situations: Copying a depth-texture example but constructing a plain Texture instead of DepthTexture. Sharing a depth attachment across render targets with the wrong type. Migrating code that previously used a non-typed depth placeholder.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/a89ad23f6345e119. Report an issue: GitHub.