-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Closed
Closed
Copy link
Description
Description
With WebGPURenderer
, a mesh using MeshStandardMaterial
with an alpha texture and alphaTest
casts a solid quad shadow, as if the cutout were ignored. This occurs both with WebGPURenderer
and with WebGPURenderer({ forceWebGL: true })
. Using WebGLRenderer
directly produces the expected cut-out shadow.
Reproduction steps
- Enable
renderer.shadowMap
and add a ground plane (receiveShadow = true
). - Create a
CanvasTexture
with a transparent background and a tall opaque rectangle. - Use
MeshStandardMaterial({ map, alphaTest: 0.5, side: DoubleSide })
. - Put the material on a plane (
castShadow = true
). - Add a shadow-casting
DirectionalLight
. - Render with
WebGPURenderer
→ shadow is a full quad; switch toWebGLRenderer
→ shadow is cut out.
Code
// Toggle to compare:
// import * as THREE from "three"; // OK: WebGLRenderer
// const renderer = new THREE.WebGLRenderer({ antialias: true });
import * as THREE from "three/webgpu"; // FAIL: WebGPURenderer
const renderer = new THREE.WebGPURenderer({
antialias: true,
// forceWebGL: true, // also reproduces
});
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
const camera = new THREE.PerspectiveCamera(40, innerWidth/innerHeight, 1, 3000);
camera.position.set(0, 1.5, 5);
const scene = new THREE.Scene();
// ground
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(10,10),
new THREE.MeshStandardMaterial({ color: 0xffffff })
);
ground.rotation.x = -Math.PI/2;
ground.receiveShadow = true;
scene.add(ground);
// alpha texture: tall opaque rectangle on transparent background
function makeAlphaTexture() {
const c = document.createElement("canvas");
c.width = c.height = 512;
const ctx = c.getContext("2d");
ctx.clearRect(0,0,512,512);
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, 128, 512);
const tex = new THREE.CanvasTexture(c);
tex.colorSpace = THREE.SRGBColorSpace;
return tex;
}
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(3,3),
new THREE.MeshStandardMaterial({
map: makeAlphaTexture(),
alphaTest: 0.5,
side: THREE.DoubleSide,
// transparent: false, // default
})
);
plane.position.set(0, 1.5, 0);
plane.castShadow = true;
scene.add(plane);
// light
const dir = new THREE.DirectionalLight(0xffffff, 5);
dir.position.set(10,10,10);
dir.castShadow = true;
scene.add(dir);
// render
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
renderer.setAnimationLoop(() => renderer.render(scene, camera));
Live example
Screenshots

Version
r179
Device
Desktop
Browser
Chrome
OS
MacOS