WebGPU renderer - webgl fallback
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGLBackend: color clear ignored after a colorWrite:false draw</title>
<style>body { font: 14px monospace; margin: 16px; } .ok { color: green; } .ko { color: crimson; }</style>
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.webgpu.js",
"three/webgpu": "https://cdn.jsdelivr.net/npm/three@0.186.1/build/three.webgpu.js"
} }
</script>
</head>
<body>
<pre id="out">running…</pre>
<script type="module">
import * as THREE from 'three/webgpu';
// Render two frames into a 4x4 target and read one pixel back.
async function run( forceWebGL, patched ) {
const renderer = new THREE.WebGPURenderer( { forceWebGL } );
await renderer.init();
// The proposed one-line fix: restore the color write mask before clearing.
if ( patched ) {
const clear = renderer.backend.clear.bind( renderer.backend );
renderer.backend.clear = ( color, ...rest ) => {
if ( color ) renderer.backend.state.setColorMask( true );
return clear( color, ...rest );
};
}
const target = new THREE.RenderTarget( 4, 4 );
const camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0.1, 10 );
camera.position.z = 1;
// Frame 1: a full-screen quad drawn with colorWrite: false (e.g. a depth-only occluder pass).
const occluderScene = new THREE.Scene();
occluderScene.add( new THREE.Mesh( new THREE.PlaneGeometry( 2, 2 ), new THREE.MeshBasicMaterial( { colorWrite: false } ) ) );
renderer.setClearColor( 0x00ff00, 1 ); // GREEN
renderer.setRenderTarget( target );
renderer.render( occluderScene, camera );
// Frame 2: an EMPTY scene, autoClear on, clear color RED. The target must read red.
renderer.setClearColor( 0xff0000, 1 ); // RED
renderer.render( new THREE.Scene(), camera );
renderer.setRenderTarget( null );
const px = await renderer.readRenderTargetPixelsAsync( target, 0, 0, 1, 1...