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

开启castShadow与receiveShadow后3D场景仍无阴影问题咨询

3D模型无法接收阴影的排查与解决

结合你的代码和场景,以下是几个关键问题点和解决方法:

1. 导入模型的子网格未开启receiveShadow

你在<primitive>上设置了receiveShadow,但Three.js中只有Mesh类型对象才有receiveShadow属性,顶层的Scene(Object3D)本身不具备该属性。需要遍历导入模型的所有子Mesh,手动开启接收阴影:

修改Model.js,添加遍历逻辑:

import { useEffect, useRef } from 'react';

export default function Model() {
  const sceneRef = useRef();

  useEffect(() => {
    // 遍历所有子对象,为Mesh开启receiveShadow
    sceneRef.current?.traverse((obj) => {
      if (obj.isMesh) {
        obj.receiveShadow = true;
      }
    });
  }, []);

  return <primitive ref={sceneRef} object={scene} />;
}

2. 材质不支持阴影

如果模型使用的是MeshBasicMaterial,它完全不参与光照和阴影计算。需要替换为MeshStandardMaterial或MeshPhysicalMaterial:
在上述遍历逻辑中添加材质检查:

import * as THREE from 'three';

// ... 遍历逻辑内
if (obj.isMesh) {
  obj.receiveShadow = true;
  // 替换不支持阴影的材质
  if (obj.material.isMeshBasicMaterial) {
    obj.material = new THREE.MeshStandardMaterial({
      color: obj.material.color,
      map: obj.material.map, // 保留原材质纹理(如果有)
    });
  }
}

3. 平行光阴影相机范围未覆盖模型

平行光的阴影相机默认是正交相机,视锥范围很小,如果模型不在这个范围内,就不会生成阴影。需要调整阴影相机参数:

修改Scene.js中的平行光配置:

<directionalLight
  intensity={0.5}
  castShadow
  shadow-mapSize={[512, 512]}
  position={calc}
>
  {/* 挂载阴影相机并设置范围,根据你的模型尺寸调整数值 */}
  <orthographicCamera
    attach="shadow-camera"
    left={-30}
    right={30}
    top={30}
    bottom={-30}
    near={0.1}
    far={100}
  />
</directionalLight>

额外验证点

  • 确认模型的位置在阴影相机的near和far之间,且在left/right/top/bottom范围内
  • 可以开启阴影相机辅助线调试:在场景中添加<shadowCameraHelper args={[directionalLight.shadow.camera]} />(需引入ShadowCameraHelper)

内容的提问来源于stack exchange,提问作者Kakisb Kakisb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 23:54:55