从零开始学习three.js(7):灯光深度解析,从基础到高级应用

413 阅读3分钟

在 Three.js 中,灯光是构建逼真 3D 场景的关键元素之一。通过合理使用灯光,可以增强物体的质感、立体感和场景的整体氛围。本文将详细介绍 Three.js 的灯光系统,包括常见的灯光类型、使用方法以及如何通过灯光打造丰富的视觉效果。

一、Three.js 灯光类型

Three.js 提供了多种灯光类型,每种类型都有其独特的用途和特性。以下是常见的灯光类型及其特点

灯光类型特点
AmbientLight环境光,均匀照亮场景中的所有物体,无方向性,不产生阴影。
DirectionalLight平行光,光线平行且方向一致,适合模拟太阳光或远处光源,可产生阴影。
PointLight点光源,从一点向四周扩散,强度随距离衰减,适合模拟灯泡或局部光源。
SpotLight聚光灯,从一点向特定方向发射锥形光束,适合模拟手电筒或舞台灯光,可产生阴影。
HemisphereLight半球光,模拟天空和地面的光照效果,适合创建自然环境光照。
RectAreaLight矩形区域光,从平面发射光线,适合模拟窗户或灯箱的光线。

二、常见灯光类型详解

2.1 环境光(AmbientLight)

环境光是最基础的光源,它没有方向性,也不会产生阴影。它主要用于提供全局光照,确保场景中没有完全黑暗的区域。

const ambientLight = new THREE.AmbientLight(0x404040, 0.5); // 灰色环境光,强度为0.5
scene.add(ambientLight);

2.2 平行光(DirectionalLight)

平行光模拟太阳光,光线平行且方向一致,适合大范围的均匀光照。它还可以产生阴影。

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 10, 7); // 设置光源位置
directionalLight.castShadow = true; // 启用阴影
scene.add(directionalLight);

2.3 点光源(PointLight)

点光源从一点向四周扩散,强度随距离衰减,适合模拟灯泡或局部光源。

const pointLight = new THREE.PointLight(0xff0000, 1, 10); // 红色点光源,强度为1,最大距离为10
pointLight.position.set(2, 3, 1);
scene.add(pointLight);

2.4 聚光灯(SpotLight)

聚光灯从一点向特定方向发射锥形光束,适合模拟手电筒或舞台灯光。

const spotLight = new THREE.SpotLight(0x00ff00, 1);
spotLight.position.set(0, 5, 0);
spotLight.angle = Math.PI / 6; // 光束角度
spotLight.penumbra = 0.5; // 柔边效果
scene.add(spotLight);

2.5 半球光(HemisphereLight)

半球光模拟天空和地面的光照效果,适合创建自然环境光照。

const hemiLight = new THREE.HemisphereLight(0x87CEEB, 0xFFFFFF, 0.6); // 天空蓝和白色光
scene.add(hemiLight);

2.6 矩形区域光(RectAreaLight)

矩形区域光从平面发射光线,适合模拟窗户或灯箱的光线。

const rectAreaLight = new THREE.RectAreaLight(0xffffff, 1, 10, 10); // 白色光,强度为1,宽度和高度为10
rectAreaLight.position.set(0, 10, 0);
scene.add(rectAreaLight);

三、阴影效果配置指南

阴影是增强场景真实感的重要元素。在 Three.js 中,只有部分灯光类型(如 DirectionalLightSpotLight)支持阴影。

  1. 启用渲染器阴影
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 柔和阴影
    
  2. 设置光源投射阴影
    directionalLight.castShadow = true;
    directionalLight.shadow.mapSize.width = 2048; // 提高分辨率
    
  3. 物体接收/投射阴影
    mesh.castShadow = true; 
    plane.receiveShadow = true;
    

四、性能优化技巧

  1. 控制灯光数量:点光源和聚光灯的计算成本较高,建议单场景不超过3-4个。
  2. 使用低分辨率阴影贴图light.shadow.mapSize.set(512,512)
  3. 衰减优化:合理设置distancedecay避免无效计算。
  4. 烘焙光照贴图:静态场景可使用预烘焙减少实时计算。

五、常见问题解答

1:灯光创建后为何不生效?

  • 确认灯光已添加到场景中
  • 检查材质类型(如MeshBasicMaterial不响应光照)

2:阴影显示异常?

  • 调整shadow.camera.near/far范围
  • 检查物体是否启用castShadow/receiveShadow

3:如何实现柔和的光照过渡?

  • 组合使用Ambient + Hemisphere + Directional Light
  • 调整灯光的intensityposition

更多three.js、cesium.js开源案例,请移至gitee.com/giser2017/t…