Three.js场景中如何让平面接收球体投射的阴影?
Three.js平面接收球体阴影问题修复
下面是代码中导致阴影不显示的问题及修复方案:
问题点与修复步骤
- Renderer阴影启用错误:代码中
renderer.shadowMap.enable = true是错误写法,正确属性为enabled - 方向光阴影相机范围未配置:DirectionalLight的阴影相机默认视锥体范围过小,无法覆盖场景中的物体,需手动调整参数
- 球体颜色值无效:
0xffff00f是非法十六进制颜色值,应改为0xffff00
修复后的完整代码
//.................SETUP................// import { WebGLRenderer, PerspectiveCamera, Scene, BoxGeometry, MeshBasicMaterial, Mesh, Group, PlaneGeometry, AxesHelper, GridHelper, DoubleSide, DirectionalLight, AmbientLight, MeshStandardMaterial, DirectionalLightHelper, Fog, TextureLoader, CubeTextureLoader, SphereGeometry, PCFSoftShadowMap, CameraHelper } from './three.module.js'; import { OrbitControls } from './q.js'; //................PROGRAM...............// var renderer, camera, scene, light, light1, geometry, material, mesh; // renderer renderer = new WebGLRenderer({canvas: document.getElementById('Canvas'), antialias: true, alpha: true}); //alpha: true 让画布透明,显示下层HTML内容 renderer.setClearColor(0x555555); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); // 修复阴影启用属性 renderer.shadowMap.enabled = true; // 使用软阴影提升视觉效果 renderer.shadowMap.type = PCFSoftShadowMap; // camera camera = new PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 6000); camera.position.set(0, 0, 100); camera.lookAt(0, 0, 0); //controls var orbitcontrol = new OrbitControls(camera, renderer.domElement) //scene scene = new Scene(); //lights //var ambientlight = new AmbientLight(0x333333); //scene.add(ambientlight); var sun = new DirectionalLight(0xffffff, 0.8); sun.castShadow = true; scene.add(sun); sun.position.set(0, 40, 0); // 配置方向光阴影相机参数,覆盖场景物体范围 sun.shadow.camera.left = -50; sun.shadow.camera.right = 50; sun.shadow.camera.top = 50; sun.shadow.camera.bottom = -50; sun.shadow.camera.near = 0.1; sun.shadow.camera.far = 100; // 添加阴影相机助手,方便调试(可根据需求移除) scene.add(new CameraHelper(sun.shadow.camera)); //fog //scene.fog = new Fog(0xffffff, 0, 200); //helpers var gridhelper = new GridHelper(10, 10); scene.add(gridhelper); var axishelper = new AxesHelper(3); scene.add(axishelper); var directionallighthelper = new DirectionalLightHelper(sun, 10, 0xff0000); scene.add(directionallighthelper); //material loaders var bildimport = new TextureLoader().load('a.jpg'); var bildimport2 = new TextureLoader().load('träd.jpg'); var textureLoader = new TextureLoader(); scene.background = textureLoader.load('a.jpg'); //objects //sphere var geometrySphere = new SphereGeometry(10, 15); var materialSphere = new MeshStandardMaterial({ // 修复无效颜色值 color: 0xffff00, flatShading: true, //wireframe: true, }); var meshSphere = new Mesh(geometrySphere, materialSphere); scene.add(meshSphere); meshSphere.position.set(0,20,0); meshSphere.castShadow = true; meshSphere.receiveShadow = true; //cube geometry = new BoxGeometry(1, 1, 1); var alt_material = [ new MeshBasicMaterial({map: bildimport2}), new MeshBasicMaterial({map: bildimport}), new MeshBasicMaterial({map: bildimport2}), new MeshBasicMaterial({map: bildimport}), new MeshBasicMaterial({map: bildimport2}), new MeshBasicMaterial({map: bildimport}), ]; material = new MeshStandardMaterial({ color: 0xff0000, map: bildimport2, }); mesh = new Mesh(geometry, alt_material); mesh.position.set(0, 50, 0); mesh.castShadow = true; scene.add(mesh); //plane var geometry2 = new PlaneGeometry(50, 50); var material2 = new MeshStandardMaterial({ color: 0xfff00, map: bildimport, side: DoubleSide, // 让平面双面着色 }); var mesh2 = new Mesh(geometry2, material2); mesh2.receiveShadow = true; scene.add(mesh2); mesh2.rotation.x = -0.5 * Math.PI; //groups //renderer loop requestAnimationFrame(render); var i = 0; var increase_of_i = 0.01; function render() { mesh.rotation.x += 0.01; mesh.rotation.y += 0.01; // mesh.position.y = 100 * Math.abs(Math.sin(i)); mesh.scale.x = 1 + Math.abs(Math.sin(2*i)); mesh.scale.y = 1 + Math.abs(Math.sin(2*i)); mesh.scale.z = 1 + Math.abs(Math.sin(2*i)); i += increase_of_i; renderer.render(scene, camera); requestAnimationFrame(render); }
额外说明
- 阴影相机助手可直观显示阴影有效范围,调试完成后可移除
- 只有支持光照的材质(如
MeshStandardMaterial)能参与阴影计算,MeshBasicMaterial不支持光照和阴影 - 若阴影清晰度不足,可调整
sun.shadow.mapSize参数,比如设置为new THREE.Vector2(2048, 2048)提升分辨率
内容的提问来源于stack exchange,提问作者William Gustafsson Knutsson
相关产品推荐
相关产品推荐

