第二部分-光照与阴影——09. 光源类型
09. 光源类型
1. 概述
光源是 Three.js 中实现真实感渲染的关键元素。不同类型的光源模拟不同的真实世界光照效果,合理使用光源可以显著提升场景的视觉效果。
┌─────────────────────────────────────────────────────────────┐ │ 光源体系 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Light (抽象基类) │ │ │ │ │ ├── AmbientLight (环境光) │ │ │ └── 均匀照亮所有面,无方向 │ │ │ │ │ ├── DirectionalLight (平行光) │ │ │ ├── 模拟太阳光 │ │ │ ├── 有方向,平行照射 │ │ │ └── 支持阴影 │ │ │ │ │ ├── PointLight (点光源) │ │ │ ├── 模拟灯泡 │ │ │ ├── 向所有方向发光 │ │ │ ├── 支持阴影 │ │ │ └── 支持衰减 │ │ │ │ │ ├── SpotLight (聚光灯) │ │ │ ├── 模拟手电筒/舞台灯光 │ │ │ ├── 圆锥形光照 │ │ │ ├── 支持阴影 │ │ │ └── 支持衰减、角度、半影 │ │ │ │ │ ├── HemisphereLight (半球光) │ │ │ ├── 模拟天空和地面的环境光 │ │ │ ├── 从上方和下方不同颜色 │ │ │ └── 不支持阴影 │ │ │ │ │ ├── RectAreaLight (矩形光) │ │ │ ├── 模拟窗户/灯带 │ │ │ ├── 矩形区域发光 │ │ │ └── 需要辅助器 │ │ │ │ │ └── LightProbe (光探针) │ │ ├── 采集环境光照信息 │ │ └── 用于高级光照 │ │ │ └─────────────────────────────────────────────────────────────┘2. Light 基类
Light 是所有光源的抽象基类。
2.1 核心属性
constlight=newTHREE.Light(color,intensity);// 颜色light.color=newTHREE.Color(0xffffff);// 强度light.intensity=1.0;// 位置(点光源、聚光灯需要)light.position.set(x,y,z);// 目标(平行光、聚光灯需要)light.target=newTHREE.Object3D();// 阴影映射light.shadow=newTHREE.LightShadow(newTHREE.PerspectiveCamera());// 接收阴影light.castShadow=true;// 是否可见light.visible=true;2.2 核心方法
// 复制光源light.copy(sourceLight);// 克隆光源constclonedLight=light.clone();// 释放内存light.dispose();3. AmbientLight(环境光)
环境光均匀照亮所有表面,没有方向性。
3.1 构造函数
newTHREE.AmbientLight(color,intensity)| 参数 | 说明 | 默认值 |
|---|---|---|
color | 光源颜色 | 0xffffff |
intensity | 光照强度 | 1 |
3.2 使用示例
// 白色环境光constambientLight=newTHREE.AmbientLight(0xffffff,0.5);scene.add(ambientLight);// 暖色环境光constwarmAmbient=newTHREE.AmbientLight(0xffaa66,0.3);// 冷色环境光constcoolAmbient=newTHREE.AmbientLight(0x6688ff,0.3);4. DirectionalLight(平行光)
平行光模拟太阳光,光线平行照射,产生明显的阴影。
4.1 构造函数
newTHREE.DirectionalLight(color,intensity)4.2 属性详解
constdirectionalLight=newTHREE.DirectionalLight(0xffffff,1);// 位置(决定光线方向)directionalLight.position.set(5,10,7);// 目标点(光线指向的点)directionalLight.target=newTHREE.Object3D();directionalLight.target.position.set(0,0,0);scene.add(directionalLight.target);// 阴影映射constshadowMap=directionalLight.shadow;shadowMap.mapSize.width=1024;// 阴影贴图宽度shadowMap.mapSize.height=1024;// 阴影贴图高度shadowMap.camera.near=0.5;// 近平面shadowMap.camera.far=50;// 远平面shadowMap.camera.left=-10;// 左边界shadowMap.camera.right=10;// 右边界shadowMap.camera.top=10;// 上边界shadowMap.camera.bottom=-10;// 下边界// 阴影参数directionalLight.castShadow=true;directionalLight.shadow.bias=0.0001;// 阴影偏移4.3 使用示例
// 创建平行光constdirectionalLight=newTHREE.DirectionalLight(0xffffff,1);directionalLight.position.set(5,10,7);directionalLight.castShadow=true;// 设置阴影范围constsize=10;directionalLight.shadow.camera.left=-size;directionalLight.shadow.camera.right=size;directionalLight.shadow.camera.top=size;directionalLight.shadow.camera.bottom=-size;directionalLight.shadow.camera.near=0.1;directionalLight.shadow.camera.far=30;scene.add(directionalLight);// 添加辅助器consthelper=newTHREE.DirectionalLightHelper(directionalLight,0.5);scene.add(helper);// 添加阴影相机辅助器constshadowHelper=newTHREE.CameraHelper(directionalLight.shadow.camera);scene.add(shadowHelper);5. PointLight(点光源)
点光源从一点向所有方向发光,模拟灯泡。
5.1 构造函数
newTHREE.PointLight(color,intensity,distance,decay)| 参数 | 说明 | 默认值 |
|---|---|---|
color | 光源颜色 | 0xffffff |
intensity | 光照强度 | 1 |
distance | 光照距离(0=无限) | 0 |
decay | 衰减系数 | 1 |
5.2 属性详解
constpointLight=newTHREE.PointLight(0xff6600,1,20,1);// 位置pointLight.position.set(2,3,4);// 光照距离pointLight.distance=20;// 衰减系数pointLight.decay=1;// 功率(替代 intensity + distance + decay)pointLight.power=100;// 流明// 阴影pointLight.castShadow=true;pointLight.shadow.mapSize.width=512;pointLight.shadow.mapSize.height=512;5.3 使用示例
// 创建点光源constpointLight=newTHREE.PointLight(0xff6600,1,20);pointLight.position.set(2,3,4);pointLight.castShadow=true;scene.add(pointLight);// 添加辅助器consthelper=newTHREE.PointLightHelper(pointLight,0.5);scene.add(helper);6. SpotLight(聚光灯)
聚光灯产生圆锥形光照,模拟手电筒或舞台灯光。
6.1 构造函数
newTHREE.SpotLight(color,intensity,distance,angle,penumbra,decay)| 参数 | 说明 | 默认值 |
|---|---|---|
color | 光源颜色 | 0xffffff |
intensity | 光照强度 | 1 |
distance | 光照距离 | 0 |
angle | 光束角度(弧度) | Math.PI / 3 |
penumbra | 半影系数(0-1) | 0 |
decay | 衰减系数 | 1 |
6.2 属性详解
constspotLight=newTHREE.SpotLight(0xffffff,1);// 位置spotLight.position.set(2,5,3);// 目标点spotLight.target=newTHREE.Object3D();spotLight.target.position.set(0,0,0);scene.add(spotLight.target);// 光束角度(弧度)spotLight.angle=Math.PI/6;// 30度// 半影系数(边缘柔和度)spotLight.penumbra=0.3;// 距离spotLight.distance=20;// 衰减spotLight.decay=1;// 阴影spotLight.castShadow=true;spotLight.shadow.mapSize.width=1024;spotLight.shadow.mapSize.height=1024;6.3 使用示例
// 创建聚光灯constspotLight=newTHREE.SpotLight(0xffffff,1);spotLight.position.set(2,5,3);spotLight.angle=Math.PI/6;spotLight.penumbra=0.3;spotLight.castShadow=true;// 设置目标consttarget=newTHREE.Object3D();target.position.set(0,0,0);spotLight.target=target;scene.add(spotLight);scene.add(target);// 添加辅助器consthelper=newTHREE.SpotLightHelper(spotLight);scene.add(helper);7. HemisphereLight(半球光)
半球光模拟天空和地面的环境光,从上方和下方用不同颜色照亮。
7.1 构造函数
newTHREE.HemisphereLight(skyColor,groundColor,intensity)| 参数 | 说明 | 默认值 |
|---|---|---|
skyColor | 天空颜色(上方) | 0xffffff |
groundColor | 地面颜色(下方) | 0xffffff |
intensity | 光照强度 | 1 |
7.2 使用示例
// 天空蓝,地面绿consthemisphereLight=newTHREE.HemisphereLight(0x88aaff,0x44aa66,0.6);scene.add(hemisphereLight);// 辅助器consthelper=newTHREE.HemisphereLightHelper(hemisphereLight,1);scene.add(helper);8. RectAreaLight(矩形光)
矩形光从矩形区域发光,需要特殊材质支持。
8.1 构造函数
newTHREE.RectAreaLight(color,intensity,width,height)8.2 使用示例
// 创建矩形光constrectLight=newTHREE.RectAreaLight(0xffffff,1,2,1);rectLight.position.set(1,2,3);rectLight.lookAt(0,0,0);scene.add(rectLight);// 辅助器(需要导入)import{RectAreaLightHelper}from'three/examples/jsm/helpers/RectAreaLightHelper.js';consthelper=newRectAreaLightHelper(rectLight);scene.add(helper);9. 光源辅助器
| 辅助器 | 用途 |
|---|---|
DirectionalLightHelper | 显示平行光方向和位置 |
PointLightHelper | 显示点光源位置 |
SpotLightHelper | 显示聚光灯圆锥范围 |
HemisphereLightHelper | 显示半球光 |
RectAreaLightHelper | 显示矩形光区域 |
CameraHelper | 显示阴影相机范围 |
10. 完整示例
import*asTHREEfrom'three';import{OrbitControls}from'three/examples/jsm/controls/OrbitControls.js';constscene=newTHREE.Scene();scene.background=newTHREE.Color(0x111122);constcamera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(8,6,12);camera.lookAt(0,0,0);constrenderer=newTHREE.WebGLRenderer({antialias:true});renderer.setSize(window.innerWidth,window.innerHeight);renderer.shadowMap.enabled=true;document.body.appendChild(renderer.domElement);constcontrols=newOrbitControls(camera,renderer.domElement);controls.enableDamping=true;// 物体constgeometry=newTHREE.SphereGeometry(1,64,64);constmaterial=newTHREE.MeshStandardMaterial({color:0x44aa88,metalness:0.5,roughness:0.3});constsphere=newTHREE.Mesh(geometry,material);sphere.castShadow=true;sphere.receiveShadow=true;scene.add(sphere);// 地面constplaneGeometry=newTHREE.PlaneGeometry(10,10);constplaneMaterial=newTHREE.MeshStandardMaterial({color:0x336699,side:THREE.DoubleSide});constplane=newTHREE.Mesh(planeGeometry,planeMaterial);plane.rotation.x=-Math.PI/2;plane.position.y=-1.5;plane.receiveShadow=true;scene.add(plane);// 环境光constambientLight=newTHREE.AmbientLight(0x404040,0.5);scene.add(ambientLight);// 平行光constdirectionalLight=newTHREE.DirectionalLight(0xffffff,1);directionalLight.position.set(5,10,7);directionalLight.castShadow=true;directionalLight.shadow.mapSize.width=1024;directionalLight.shadow.mapSize.height=1024;scene.add(directionalLight);// 点光源constpointLight=newTHREE.PointLight(0xff6600,0.8,15);pointLight.position.set(2,2,3);pointLight.castShadow=true;scene.add(pointLight);// 聚光灯constspotLight=newTHREE.SpotLight(0x44aaff,0.6);spotLight.position.set(-3,4,2);spotLight.angle=Math.PI/6;spotLight.penumbra=0.3;spotLight.castShadow=true;constspotTarget=newTHREE.Object3D();spotTarget.position.set(0,0,0);spotLight.target=spotTarget;scene.add(spotLight);scene.add(spotTarget);// 辅助器constdirectionalHelper=newTHREE.DirectionalLightHelper(directionalLight,0.5);scene.add(directionalHelper);constpointHelper=newTHREE.PointLightHelper(pointLight,0.3);scene.add(pointHelper);constspotHelper=newTHREE.SpotLightHelper(spotLight);scene.add(spotHelper);// 辅助对象constaxesHelper=newTHREE.AxesHelper(5);scene.add(axesHelper);constgridHelper=newTHREE.GridHelper(15,20);scene.add(gridHelper);// 动画functionanimate(){requestAnimationFrame(animate);// 移动点光源consttime=Date.now()*0.002;pointLight.position.x=2+Math.sin(time)*1.5;pointLight.position.z=3+Math.cos(time)*1.5;// 旋转聚光灯spotLight.position.x=-3+Math.sin(time*0.5)*1;controls.update();renderer.render(scene,camera);}animate();window.addEventListener('resize',onWindowResize,false);functiononWindowResize(){camera.aspect=window.innerWidth/window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth,window.innerHeight);}11. 总结
| 光源类型 | 特点 | 适用场景 | 支持阴影 |
|---|---|---|---|
| AmbientLight | 均匀照亮,无方向 | 基础照明 | ❌ |
| DirectionalLight | 平行光,有方向 | 太阳光 | ✅ |
| PointLight | 点光源,向四周 | 灯泡 | ✅ |
| SpotLight | 圆锥形光束 | 手电筒、舞台 | ✅ |
| HemisphereLight | 上下不同颜色 | 室外环境 | ❌ |
| RectAreaLight | 矩形区域 | 窗户、灯带 | ✅ |
| 光源属性 | 说明 |
|---|---|
color | 光源颜色 |
intensity | 光照强度 |
position | 光源位置 |
target | 目标点 |
castShadow | 是否投射阴影 |
distance | 光照距离 |
decay | 衰减系数 |
angle | 聚光灯角度 |
penumbra | 聚光灯半影 |
