如何在Three.js中为PointLight(点光源)实现软阴影效果?
在Three.js中为PointLight实现软阴影效果的方法
当然可以实现你想要的这种柔和阴影效果!下面我会一步步拆解具体操作,照着调整就能调出类似参考图里的软阴影:
1. 先搞定基础的阴影开启设置
首先得让整个场景的阴影系统跑起来,这是前提:
- 给渲染器开启阴影支持,同时指定软阴影的映射类型:
renderer.shadowMap.enabled = true; // 推荐用PCFSoftShadowMap,它能提供自然的软阴影效果,也可以试试VSMShadowMap renderer.shadowMap.type = THREE.PCFSoftShadowMap; - 让PointLight具备投射阴影的能力:
const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.castShadow = true; scene.add(pointLight); - 别忘了给场景里的物体设置阴影属性:
// 比如地面这类需要接收阴影的物体 ground.receiveShadow = true; // 像立方体这类要投射阴影的物体 cube.castShadow = true;
2. 调整PointLight的阴影参数实现软化
PointLight的阴影基于立方体阴影贴图,要让阴影变软,重点调这几个参数:
- 提升阴影贴图分辨率:更高的分辨率能减少阴影锯齿,让边缘更细腻,注意别太夸张影响性能:
pointLight.shadow.mapSize.width = 2048; pointLight.shadow.mapSize.height = 2048; - 合理设置阴影相机范围:确保阴影区域落在相机的可视范围内,避免阴影被裁剪:
pointLight.shadow.camera.near = 0.1; pointLight.shadow.camera.far = 50; - 调整阴影模糊度:通过
radius控制阴影边缘的柔和程度,值越大阴影越软;bias用来解决阴影 acne(表面出现的斑驳噪点)问题,微调即可:pointLight.shadow.radius = 8; // 可以根据效果慢慢调整这个值 pointLight.shadow.bias = -0.0001;
3. 额外优化小技巧
- 如果PCFSoftShadowMap的效果还达不到预期,可以尝试
THREE.VSMShadowMap,它能实现更平滑的软阴影,但对性能要求稍高,需要多测试参数避免噪点。 - 场景里如果有太多复杂模型投射阴影,会拖慢性能,必要时可以简化模型几何体来平衡效果和性能。
给你个完整的示例片段,方便你直接参考测试:
// 初始化渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; document.body.appendChild(renderer.domElement); // 场景与相机 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); camera.position.z = 5; // 配置点光源 const pointLight = new THREE.PointLight(0xffffff, 1); pointLight.position.set(2, 2, 2); pointLight.castShadow = true; // 阴影参数配置 pointLight.shadow.mapSize.set(2048, 2048); pointLight.shadow.camera.near = 0.1; pointLight.shadow.camera.far = 20; pointLight.shadow.radius = 8; pointLight.shadow.bias = -0.0001; scene.add(pointLight); // 地面(接收阴影) const groundGeometry = new THREE.PlaneGeometry(10, 10); const groundMaterial = new THREE.MeshStandardMaterial({color: 0x808080}); const ground = new THREE.Mesh(groundGeometry, groundMaterial); ground.rotation.x = -Math.PI/2; ground.position.y = -2; ground.receiveShadow = true; scene.add(ground); // 立方体(投射阴影) const cubeGeometry = new THREE.BoxGeometry(1,1,1); const cubeMaterial = new THREE.MeshStandardMaterial({color: 0xff0000}); const cube = new THREE.Mesh(cubeGeometry, cubeMaterial); cube.position.set(0, 0, 0); cube.castShadow = true; scene.add(cube); // 渲染循环 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
照着这些步骤调整,你就能得到类似参考图里的软阴影效果啦,记得根据自己的场景大小和性能需求微调参数哦!
内容的提问来源于stack exchange,提问作者Josh Becker
相关产品推荐
相关产品推荐

