环境光AmbientLight
环境光会均匀的照亮场景中的所有物体。
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
// 等价于下面
const ambientLight = new THREE.AmbientLight()
ambientLight.color = new THREE.Color(0xffffff)
// 光强
ambientLight.intensity = 0.5
平行光DirectionalLight
平行光是沿着特定方向发射的光。这种光的表现像是无限远,从它发出的光线都是平行的。常常用平行光来模拟太阳光的效果。
// 平行光
const directionalLight = new THREE.DirectionalLight(0x00fffc,0.5)
directionalLight.position.set(1,0.25,0)
scene.add(directionalLight)
半球光HemisphereLight
光源直接放置于场景之上,光照颜色从天空光线颜色渐变到地面光线颜色。
半球光不能投射阴影。
HemisphereLight( skyColor : Integer, groundColor : Integer, intensity : Float )
skyColor
- (可选参数) 天空中发出光线的颜色。 缺省值 0xffffff。
groundColor
- (可选参数) 地面发出光线的颜色。 缺省值 0xffffff。
intensity
- (可选参数) 光照强度。 缺省值 1。
//半球光
const hemisphereLight = new THREE.HemisphereLight(0xff0000,0x0000ff,0.3)
scene.add(hemisphereLight)
点光源PointLight
从一个点向各个方向发射的光源。一个常见的例子是模拟一个灯泡发出的光。
PointLight( color : Integer, intensity : Float, distance : Number, decay : Float )
color
- (可选参数)) 十六进制光照颜色。 缺省值 0xffffff (白色)。
intensity
- (可选参数) 光照强度。 缺省值 1。
distance
- 这个距离表示从光源到光照强度为0的位置。 当设置为0时,光永远不会消失(距离无穷大)。缺省值 0.
decay
- 沿着光照距离的衰退量。缺省值 1。 在 physically correct 模式中,decay = 2。
const pointLight = new THREE.PointLight(0xff9000, 0.5)
// pointLight.position.x = 2
// pointLight.position.y = 3
// pointLight.position.z = 4
pointLight.position.set(1,-0.5,1)
scene.add(pointLight)
平面光光源RectAreaLight
平面光光源从一个矩形平面上均匀地发射光线。这种光源可以用来模拟像明亮的窗户或者条状灯光光源。
注意事项:
不支持阴影。
只支持 MeshStandardMaterial 和 MeshPhysicalMaterial 两种材质。
你必须在你的场景中加入 RectAreaLightUniformsLib ,并调用init()。
RectAreaLight( color : Integer, intensity : Float, width : Float, height : Float )
color
- (可选参数) 十六进制数字表示的光照颜色。缺省值为 0xffffff (白色)
intensity
- (可选参数) 光源强度/亮度 。缺省值为 1。
width
- (可选参数) 光源宽度。缺省值为 10。
height
- (可选参数) 光源高度。缺省值为 10。
//平面光光源
const rectAreaLight = new THREE.RectAreaLight(0x4e00ff,2,1,1)
rectAreaLight.position.set(-1.5,0,1.5)
// 设置平面光照向场景中心
rectAreaLight.lookAt(new THREE.Vector3())
scene.add(rectAreaLight)
聚光灯SpotLight
光线从一个点沿一个方向射出,就像手电筒,随着光线照射的变远,光线圆锥体的尺寸也逐渐增大。
SpotLight( color : Integer, intensity : Float, distance : Float, angle : Radians, penumbra : Float, decay : Float )
color
- (可选参数) 十六进制光照颜色。 缺省值 0xffffff (白色)。
intensity
- (可选参数) 光照强度。 缺省值 1。
distance
- 从光源发出光的最大距离,其强度根据光源的距离线性衰减。
angle
- 光线散射角度,最大为Math.PI/2。
penumbra
- 聚光锥的半影衰减百分比。在0和1之间的值。默认为0(光影边缘很锐利)。
decay
- 沿着光照距离的衰减量。
// 聚光灯
const spotLight = new THREE.SpotLight(0x78ff00, 0.5, 10, Math.PI * 0.1, 0.25, 1)
spotLight.position.set(0, 2, 3)
scene.add(spotLight)
如果要旋转聚光灯改变其方向,则需要往场景加入聚光灯的target属性,然后再设置其位置
scene.add(spotLight.target)
spotLight.target.position.x = -0.75
性能消耗问题
灯光可以造成许多性能消耗,因此需尽可能少的添加光源或使用轻量级光源。
消耗最小的:环境光AmbientLight和半球光HemisphereLight
消耗适中的:平行光DirectionalLight和点光源PointLight
消耗最高的:聚光灯SpotLight和平面光光源RectAreaLight
解决方案
可以在物体材质中进行烤光(Bake Light)
辅助对象
为了帮助我们更好定位光源位置,可以使用些辅助对象
//Helpers
// 半球光辅助
const hemisphereLightHelper = new THREE.HemisphereLightHelper(hemisphereLight,0.2)
// 平行光辅助
const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight,0.2)
// 点光源辅助
const pointLightHelper = new THREE.PointLightHelper(pointLight,0.2)
scene.add(hemisphereLightHelper,directionalLightHelper,pointLightHelper)
聚光灯辅助对象没有size属性。如果我们移动了聚光灯朝向,那么聚光灯辅助对象也需要更新。
const spotLightHelper = new THREE.SpotLightHelper(spotLight)
scene.add(spotLightHelper)
window.requestAnimationFrame(()=>{
spotLightHelper.update()
})
平面光光源辅助对象不是three.js的一部分,所以需要另外引入
import { RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js'
const rectAreaLightHelper = new RectAreaLightHelper(rectAreaLight)
scene.add(rectAreaLightHelper)
window.requestAnimationFrame(()=>{
rectAreaLightHelper.position.copy(rectAreaLight.position)
rectAreaLightHelper.quaternion.copy(rectAreaLight.quaternion)
rectAreaLightHelper.update()
})