[v11] Verify useDepthBuffer: core and webgpu implementations both exist
What it does
src/core/Helpers/useDepthBuffer/useDepthBuffer.ts:21-25:
useFrame((state) => {
...
state.gl.setRenderTarget(depthFBO)
state.gl.render(state.scene, state.camera)
state.gl.setRenderTarget(null)
})Note this hook also has a WebGPU implementation at src/webgpu/Helpers/useDepthBuffer/useDepthBuffer.ts, which uses TSL. So there are two live implementations and the core one is what the root entry serves — including to WebGPU users.
What to check
- Which implementation actually reaches a WebGPU user, and whether that is intended. If the WebGPU one is the correct implementation, the core one reaching WebGPU through the root entry is the bug.
- Depth textures are the least portable part of the render-target API. Confirm the FBO's depth attachment is created correctly under the WebGPU build and that sampling it produces the same values —
ContactShadowsandMeshReflectorMaterialboth consume depth this way. setRenderTarget(null)restores to the default framebuffer rather than the previous target, same concern as the cameras.state.glvsstate.renderer— deprecated accessor, warns every frame.
Shared context (identical across all seven)
These components are classified agnostic — they live in core/, so they are assumed to work on both renderers. That assumption held for 104 of the 106 agnostic components when swept: 73 never touch the renderer at all, and 31 touch only members both renderers have. These seven are different: they drive their own render calls, and that is where semantics diverge even when the API surface matches. See #2818.
setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) has an identical signature on both (Renderer.js:2578 vs WebGLRenderer.js:2890), so that part is fine.
render() is where they differ — three/src/renderers/common/Renderer.js:1362:
render( scene, camera ) {
if ( this._initialized === false ) {
throw new Error( 'THREE.Renderer: .render() called before the backend is initialized. Use "await renderer.init();" before rendering.' );
}
this._renderScene( scene, camera );
}WebGL has no such gate. A render() that happens before the backend is ready throws on WebGPU and silently works on WebGL.
This is the class of bug that produced #2809: Preload calls gl.compile(), which on WebGPU is a getter aliasing compileAsync — same name, returns an unawaited promise, so preloading never happens. Grep cannot find these; they need reading.
Acceptance
Read the component against the WebGPU Renderer implementation and either confirm it is correct or fix it and say what was wrong. A story exercising the render path on WebGPU is the evidence — note Setup sets frameloop: 'never' under test, so useFrame does not run there and a green story proves nothing about this.
Source: pmndrs/drei