2.1光照类型 Three.js 光照类型详解 在 Three.js 中,光照是创建逼真 3D 场景的关键因素。光照不仅能照亮物体,还能产生阴影,从而增加场景的深度和真实感。Three.js 提供了多种光照类型,每种光照类型都有其独特的属性和适用场景。 2.1 光照类型 Three.js 提供了以下几种主要的光照类型: AmbientLight (环境光):均匀地照亮场景中的所有物体,没有特定方向。 DirectionalLight (平行光/方向光):模拟来自无限远处的光源,例如太阳光。 PointLight (点光源):从一个点向所有方向发射光线,类似于灯泡。 SpotLight (聚光灯):从一个点向一个锥形区域发射光线,类似于舞台上的聚光灯。
在 Three.js 中,光照是创建逼真 3D 场景的关键因素。光照不仅能照亮物体,还能产生阴影,从而增加场景的深度和真实感。Three.js 提供了多种光照类型,每种光照类型都有其独特的属性和适用场景。
Three.js 提供了以下几种主要的光照类型:
AmbientLight (环境光):均匀地照亮场景中的所有物体,没有特定方向。
DirectionalLight (平行光/方向光):模拟来自无限远处的光源,例如太阳光。
PointLight (点光源):从一个点向所有方向发射光线,类似于灯泡。
SpotLight (聚光灯):从一个点向一个锥形区域发射光线,类似于舞台上的聚光灯。
HemisphereLight (半球光):模拟室外环境光,从天空和地面分别发射不同颜色的光线。
RectAreaLight (矩形区域光):从一个矩形区域发射光线,更接近真实世界的光照效果 (需要特定的渲染器)。
下面我们将逐一介绍这些光照类型,并提供相应的代码示例。
环境光会均匀地照亮场景中的所有物体,它没有特定的方向,因此不会产生阴影。环境光通常用于模拟场景中的全局照明,或者作为其他光照类型的补充,以避免场景中出现完全黑暗的区域。
import * as THREE from 'three'; // 创建场景 const scene = new THREE.Scene(); // 创建环境光 const ambientLight = new THREE.AmbientLight(0xffffff, 0.5); // 颜色,强度 scene.add(ambientLight); // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
THREE.AmbientLight(color, intensity):创建环境光,color 是光的颜色 (十六进制或颜色名称),intensity 是光的强度 (0.0 到 1.0)。适用场景:
作为场景的基础照明。
填充阴影区域,使其不至于完全黑暗。
平行光模拟来自无限远处的光源,例如太阳光。所有光线都沿着相同的方向平行传播。平行光会产生清晰的阴影。
import * as THREE from 'three'; // 创建场景 const scene = new THREE.Scene(); // 创建平行光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5); // 颜色,强度 directionalLight.position.set(5, 3, 5); // 设置光照方向 scene.add(directionalLight); // 开启阴影投射 directionalLight.castShadow = true; // 设置阴影贴图的分辨率 directionalLight.shadow.mapSize.width = 1024; directionalLight.shadow.mapSize.height = 1024; // 设置阴影的可见区域 directionalLight.shadow.camera.near = 0.5; directionalLight.shadow.camera.far = 50; // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); cube.castShadow = true; // 允许立方体投射阴影 scene.add(cube); // 创建一个平面 const planeGeometry = new THREE.PlaneGeometry(10, 10); const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -Math.PI / 2; // 旋转平面使其水平 plane.receiveShadow = true; // 允许平面接收阴影 scene.add(plane); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; 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 ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
THREE.DirectionalLight(color, intensity):创建平行光,color 是光的颜色,intensity 是光的强度。
directionalLight.position.set(x, y, z):设置光照方向。
directionalLight.castShadow = true:开启阴影投射。
directionalLight.shadow.mapSize.width 和 directionalLight.shadow.mapSize.height:设置阴影贴图的分辨率。分辨率越高,阴影越清晰,但性能消耗也越大。
directionalLight.shadow.camera.near 和 directionalLight.shadow.camera.far:设置阴影相机的近平面和远平面。这些值决定了阴影的可见区域。
cube.castShadow = true:允许立方体投射阴影。
plane.receiveShadow = true:允许平面接收阴影。
renderer.shadowMap.enabled = true:启用阴影贴图。
renderer.shadowMap.type = THREE.PCFSoftShadowMap:设置阴影贴图类型。PCFSoftShadowMap 是一种常用的软阴影算法,可以减少阴影的锯齿感。
适用场景:
模拟太阳光或月光。
需要清晰阴影的场景。
点光源从一个点向所有方向发射光线,类似于灯泡。点光源会产生球形光照效果,并且可以衰减。
import * as THREE from 'three'; // 创建场景 const scene = new THREE.Scene(); // 创建点光源 const pointLight = new THREE.PointLight(0xffffff, 1, 100); // 颜色,强度,距离 pointLight.position.set(0, 3, 0); // 设置光源位置 scene.add(pointLight); // 开启阴影投射 pointLight.castShadow = true; // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); cube.castShadow = true; scene.add(cube); // 创建一个平面 const planeGeometry = new THREE.PlaneGeometry(10, 10); const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -Math.PI / 2; plane.receiveShadow = true; scene.add(plane); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; 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 ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
THREE.PointLight(color, intensity, distance, decay):创建点光源,color 是光的颜色,intensity 是光的强度,distance 是光照距离,decay 是光照衰减。
pointLight.position.set(x, y, z):设置光源位置。
pointLight.distance:设置光照距离。当光线传播的距离超过这个值时,光强会降为 0。
pointLight.decay:设置光照衰减。默认值为 1,表示光强随距离的平方衰减。设置为 2 会使衰减更快,设置为 0 则不会衰减。
适用场景:
模拟灯泡、蜡烛等光源。
需要局部照明的场景。
聚光灯从一个点向一个锥形区域发射光线,类似于舞台上的聚光灯。聚光灯具有方向、角度和衰减等属性。
import * as THREE from 'three'; // 创建场景 const scene = new THREE.Scene(); // 创建聚光灯 const spotLight = new THREE.SpotLight(0xffffff, 1, 100, Math.PI / 6, 0.2); // 颜色,强度,距离,角度,半影 spotLight.position.set(0, 5, 0); // 设置光源位置 spotLight.target.position.set(0, 0, 0); // 设置光照目标 scene.add(spotLight); scene.add(spotLight.target); // 开启阴影投射 spotLight.castShadow = true; // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); cube.castShadow = true; scene.add(cube); // 创建一个平面 const planeGeometry = new THREE.PlaneGeometry(10, 10); const planeMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 }); const plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = -Math.PI / 2; plane.receiveShadow = true; scene.add(plane); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; 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 ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
THREE.SpotLight(color, intensity, distance, angle, penumbra, decay):创建聚光灯,color 是光的颜色,intensity 是光的强度,distance 是光照距离,angle 是光照角度,penumbra 是半影大小,decay 是光照衰减。
spotLight.position.set(x, y, z):设置光源位置。
spotLight.target.position.set(x, y, z):设置光照目标。
spotLight.angle:设置光照角度,单位是弧度。
spotLight.penumbra:设置半影大小,范围是 0 到 1。半影越大,光照边缘越柔和。
适用场景:
模拟舞台聚光灯、手电筒等光源。
需要精确控制光照范围的场景。
半球光模拟室外环境光,从天空和地面分别发射不同颜色的光线。半球光没有特定的方向,通常用于模拟天空和地面的散射光。
import * as THREE from 'three'; // 创建场景 const scene = new THREE.Scene(); // 创建半球光 const hemisphereLight = new THREE.HemisphereLight(0xffffff, 0x000000, 0.5); // 天空颜色,地面颜色,强度 scene.add(hemisphereLight); // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
THREE.HemisphereLight(skyColor, groundColor, intensity):创建半球光,skyColor 是天空颜色,groundColor 是地面颜色,intensity 是光的强度。适用场景:
模拟室外环境光。
作为场景的基础照明。
矩形区域光从一个矩形区域发射光线,更接近真实世界的光照效果。需要注意的是,RectAreaLight 需要使用 WebGLRenderer 的 RectAreaLightUniformsLib 才能正确渲染。
import * as THREE from 'three'; import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js'; import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js'; // 创建场景 const scene = new THREE.Scene(); // 初始化 RectAreaLightUniformsLib RectAreaLightUniformsLib.init(); // 创建矩形区域光 const rectAreaLight = new THREE.RectAreaLight(0xffffff, 5, 4, 10); // 颜色,强度,宽度,高度 rectAreaLight.position.set(5, 5, 0); rectAreaLight.lookAt(0,0,0); scene.add(rectAreaLight); // 添加 RectAreaLightHelper (可选) const rectAreaLightHelper = new RectAreaLightHelper( rectAreaLight ); rectAreaLight.add( rectAreaLightHelper ); // 创建一个立方体 const geometry = new THREE.BoxGeometry(1, 1, 1); const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建相机和渲染器(省略,参考完整代码) const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); camera.position.z = 10; camera.position.y = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // 渲染循环 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
代码解释:
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js':导入 RectAreaLightUniformsLib。
RectAreaLightUniformsLib.init():初始化 RectAreaLightUniformsLib。
THREE.RectAreaLight(color, intensity, width, height):创建矩形区域光,color 是光的颜色,intensity 是光的强度,width 是矩形宽度,height 是矩形高度。
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js':导入 RectAreaLightHelper,这是一个可选的辅助工具,用于可视化矩形区域光。
适用场景:
模拟窗户、发光面板等光源。
需要更真实光照效果的场景。
Three.js 提供了多种光照类型,每种光照类型都有其独特的属性和适用场景。选择合适的光照类型,并调整其参数,可以创建出逼真、生动的 3D 场景。在实际开发中,通常需要结合多种光照类型,才能达到最佳效果。
希望这篇文章能够帮助你更好地理解 Three.js 中的光照类型。