开启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
相关产品推荐
相关产品推荐

