You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 12:09:56