从零开始学习three.js(8):一文详解three.js中的灯光Light

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

一、Three.js 灯光类型

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

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

二、常见灯光类型详解

2.1 环境光(AmbientLight)

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

构造函数:

new THREE.AmbientLight(color, intensity);

属性:

  • color:光的颜色(十六进制或CSS字符串),默认 0xffffff(白色)。
  • intensity:光强,默认 1。

示例:

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

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

构造函数:

new THREE.DirectionalLight(color, intensity);

属性:

  • color:光的颜色(十六进制或CSS字符串),默认 0xffffff(白色)。
  • intensity:光强,默认 1。
  • position:光源位置(方向由位置和目标点计算)。
  • target:光的照射目标(默认为场景原点)。

阴影:

  • castShadow = true 开启阴影。
  • shadow 属性控制阴影参数(如 shadow.mapSize 和 shadow.camera)。

示例:

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

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

构造函数:

new THREE.PointLight(color, intensity, distance, decay);

属性:

  • color:光的颜色(十六进制或CSS字符串),默认 0xffffff(白色)。
  • intensity:光强,默认 1。
  • position:光源位置(方向由位置和目标点计算)。
  • distance:光的最大照射距离(超过后衰减为0),默认 0(无限远)。
  • decay:衰减系数(物理衰减模型),默认 2。

阴影:

  • castShadow = true 开启阴影。
  • shadow 属性控制阴影参数(如 shadow.mapSize 和 shadow.camera)。

示例:

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

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

构造函数:

new THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);

属性:

  • color:光的颜色(十六进制或CSS字符串),默认 0xffffff(白色)。
  • intensity:光强,默认 1。
  • position 和 target:定义光源位置和方向。
  • distance:光的最大照射距离(超过后衰减为0),默认 0(无限远)。
  • angle:光束角度(弧度),默认 Math.PI / 3(60度)。
  • penumbra:光锥边缘的衰减比例(0~1),默认 0。
  • decay:衰减系数(物理衰减模型),默认 2。

阴影:

  • castShadow = true 开启阴影。
  • shadow 属性控制阴影参数(如 shadow.mapSize 和 shadow.camera)。

示例:

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)

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

构造函数:

new THREE.HemisphereLight(skyColor, groundColor, intensity);

属性:

  • skyColor:天空颜色,默认 0xffffff。
  • groundColor:地面颜色,默认 0xffffff。
  • intensity:光强,默认 1。

示例:

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

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

构造函数:

new THREE.RectAreaLight(color, intensity, width, height);

属性:

  • color:颜色,默认 0xffffff。
  • intensity:光强,默认 1。
  • width:光源宽度,默认 10。
  • height:光源高度,默认 10。
  • position 和 rotation:定义光源位置和方向。

注意: 需引入 RectAreaLightUniformsLib(Three.js r113+)。

示例:

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…

你可能感兴趣的:(three.js,学习,javascript,开发语言,webgl,数据可视化,前端)