# 一、光照

# 1. 光的可视化

1
2
const lighthelper = new THREE.LightHelper(light) //light为创建的光
scene.add(lighth)

# 2. 环境光

​ 环境光没有方向且无法产生阴影,添加进场景中,所有能受光照影响的材质都会有这个环境光。

1
2
const ambientLight = new THREE.AmbientLight(color,intensity)//color为颜色,intensity为强度
scene.add(ambientLight)

# 3. 平行光

​ 一组平行的光,能够产生阴影。由于太阳离地球足够远所以太阳光对于地球而言会被认为一组平行光,threejs 的平行光可以用来模拟太阳光。

1
2
3
4
const directionalLight = new THREE.DirectionalLight(color,intensity)
directionalLight.position.set(x,y,z) //设置光光源方向
directionalLight.target = mesh //设置光源照射的物体,如果不设置默认是0,0,0
scene.add(directionalLight)

# 4. 半球光

​ 用于模拟来自天空的光照。该光照有两个颜色分别是天空的颜色和地面的颜色。该光照无法产生阴影。该光照与环境光类似,物体上方会出现天空的颜色,下方为地面的颜色,中间为这两种颜色的过渡。

1
2
const HemisphereLight = new HemisphereLight(skycolor,groundcolor,intensity)
scene.add(HemisphereLight)

# 5. 点光源

​ 点光源从某点出发向四周发射光线同时光线的强度随距离的增加在减少。点光源可以产生阴影。点光源用于模拟灯泡等照明物体。

1
2
3
4
const pointlight = new THREE.PointLight(color,intensity)
pointlight.position.set(x,y,z)//设置点光源的位置
pointlight.distance = //设置光到光照强度为0的距离
pointlight.decay = //设置光的衰减系数

# 6. 平面光光源

​ 从一个矩形平面发射光,类似于拍摄现场的打光灯可以用于模拟窗户透进来的光。不产生阴影同时只支持 MeshStandardMaterial 和 MeshPhysicalMaterial 两种 pbr 材质。

1
2
3
4
//width为发射面宽度,默认为10,height为发射面的高度
const rectAreaLight = new THREE.RectAreaLight(color,intensity,width,height)
rectAreaLight.position.set(x,y,z)
rectAreaLight.lookAt(new THREE.Vector3())//设置光照方向

# 7. 聚光灯

​ 从一点出发向某个方向发射光线,轨迹为圆锥,可以模拟手电筒。可以产生阴影

1
2
3
4
const spotLight = new THREE.SpotLight(color,initensity,distance,angle,penumbra,decay)
distance为光照发射的最大距离
angle为发射角度,因为轨迹为圆锥切面为三角形,而这个角度就是三角形的顶角
penumbra 值越大光的边缘就越柔和,默认为1即最大值。

# 二、阴影

​ threejs 提供的光源只有点光源,平行光源和聚光灯可以产生阴影。要产生阴影要光和接受光源的物体 (材质必须受光影响) 以及 renderer 开启阴影,还需要有物体接受阴影一般是平面接受阴影.

# 1. 产生阴影

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1.创建产生阴影的物体和接受阴影的平面
const geometry = new THREE.BoxGeometry(2,2,2) //创建一个球体
const material = new THREE.MeshStandardMaterial( { color:0xffffff} ) //将纹理放在材质上
const mesh = new THREE.Mesh(geometry,material)
mesh.position.set(0,1,0) //设置物体位置的方法
const plane = new THREE.Mesh(new THREE.PlaneGeometry(10,10),material)
plane.rotation.set(-Math.PI/2,0,0)
plane.position.set(0,0.1,0)
mesh.castShadow = true //物体开启阴影
plane.receiveShadow = true //平面接受阴影
scene.add(mesh,plane)
2.添加产生阴影的光源并开启阴影
const directionalLight = new THREE.DirectionalLight(0xffffff, 1,0)
directionalLight.position.set(10,10,10) //设置光光源位置
directionalLight.target = mesh //设置光源照射的物体,如果不设置默认是0,0,0
directionalLight.castShadow = true
scene.add(directionalLight)
3.渲染器开启阴影
//要先给渲染器开启阴影再渲染,顺序不能反。
renderer.shadowMap.enabled = true //渲染器开启阴影
renderer.render(scene,camera) //将场景和相机放入渲染器

# 2. 设置阴影

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//设置阴影宽高,该值越大效果越好
directionalLight.shadow.mapSize.width = 1024
directionalLight.shadow.mapSize.height = 1024
//设置阴影范围,另外平行光照射区域为长方体类似正交投影的可视区域
directionalLight.shadow.camera.near
directionalLight.shadow.camera.far
directionalLight.shadow.camera.top
directionalLight.shadow.camera.right
directionalLight.shadow.camera.bottom
directionalLight.shadow.camera.left
//阴影边缘弱化
directionalLight.shadow.radius = 5
scene.add(directionalLight)
//投影算法,有三种分别为BasicShadowMap,PCFShadowMap,PCFSoftShadowMap。效果由差到好,性能开销越来越大。
renderer.shadowMap.type