Three.js WebGPU 167版重复阴影问题:物体上下均出现阴影
解决three.js WebGPU 167版本对数深度缓冲下的错误阴影问题
问题背景
使用three.js WebGPU 167版本构建场景:两块地板之间放置球体,上方平行光直射向下。启用对数深度缓冲时,球体在顶部地板投射了错误阴影;禁用对数深度缓冲可缓解,但场景必须依赖该功能。此问题为WebGPU Renderer特有,WebGL Renderer无此异常,且不想通过设置顶部地板receiveShadow = false来禁用其阴影接收能力。
临时修复方案
1. 限制阴影相机视锥体范围
通过缩小平行光阴影相机的视锥体,使其仅覆盖需要计算阴影的区域(球体和下方地板),避免顶部地板进入阴影计算范围:
// 配置平行光阴影相机参数 directionalLight.shadow.camera.top = 5; directionalLight.shadow.camera.bottom = -5; directionalLight.shadow.camera.left = -5; directionalLight.shadow.camera.right = 5; directionalLight.shadow.camera.near = 0.1; directionalLight.shadow.camera.far = 20; // 更新投影矩阵 directionalLight.shadow.camera.updateProjectionMatrix();
此方法通过减少阴影相机的可视区域,从根源上避免顶部地板被纳入阴影计算流程。
2. 自定义材质修正深度计算逻辑
针对顶部地板的材质,重写对数深度缓冲的顶点着色器逻辑,修正反向深度值导致的阴影误判:
const customFloorMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff }); customFloorMaterial.onBeforeCompile = (shader) => { shader.vertexShader = shader.vertexShader.replace( '#include <logdepthbuf_vertex>', ` #ifdef USE_LOGDEPTHBUF_EXT gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0; gl_Position.z *= gl_Position.w; #else gl_Position.z = ( log2( gl_Position.w * 0.5 + 0.5 ) ) * logDepthBufFC - 1.0; gl_Position.z *= gl_Position.w; #endif // 修正反向深度,避免错误的深度比较 if ( gl_Position.z > gl_Position.w ) gl_Position.z = gl_Position.w - EPSILON; ` ); }; // 给顶部地板应用自定义材质 topFloorMesh.material = customFloorMaterial;
该方案通过调整顶点着色器中的深度计算,修正对数深度缓冲下的深度值异常,避免阴影被错误投射到顶部地板。
3. 等待官方修复
此问题已作为bug提交至three.js官方仓库,并在社区论坛展开讨论,属于WebGPU Renderer与对数深度缓冲的兼容性问题。后续版本大概率会推出正式修复,可关注项目更新日志获取修复信息。
内容的提问来源于stack exchange,提问作者Pershing
相关产品推荐
相关产品推荐

