【Three.js】知识梳理六:深入理解Three.js中的光源、光照和阴影投影
1. 光源光照
Three.js 提供了多种类型的光源,可以根据需要选择合适的光源类型。本节将介绍几种常见的光源类型。
1.1 添加光源
1.11 环境光(AmbientLight)
环境光是一种没有方向的光源,会均匀地照射到场景中的所有物体。通常用于模拟间接光照,为场景提供基本的照明。
import { AmbientLight } from 'three';
const ambientLight = new AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
1.12 点光源(PointLight)
点光源是一个从特定位置向所有方向发光的光源。模拟如灯泡等实际光源。
import { PointLight } from 'three';
const pointLight = new PointLight(0xffffff, 1, 100);
pointLight.position.set(0, 5, 0);
scene.add(pointLight);
1.13 平行光(DirectionalLight)
平行光是一种模拟无限远光源(如太阳)的光源。所有光线都是平行的,有一个统一的方向。
import { DirectionalLight } from 'three';
const directionalLight = new DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
1.14 聚光灯(SpotLight)
聚光灯是一种从特定位置向一个方向发散的光源。光源有一个锥形的照射范围,可以模拟手电筒、舞台灯等光源效果。
import { SpotLight } from 'three';
const spotLight = new SpotLight(0xffffff, 1);
spotLight.position.set(0, 10, 0);
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.1;
spotLight.distance = 20;
spotLight.decay = 2;
scene.add(spotLight);
1.15 半球光源(HemisphereLight)
半球光源是一种特殊类型的光源,模拟天空和地面的间接光照。它有两个颜色属性,分别表示天空颜色和地面颜色。
import { HemisphereLight } from 'three';
const hemisphereLight = new HemisphereLight(0x0000ff, 0xff0000, 0.6);
scene.add(hemisphereLight);
1.2 材质与光照
为了让物体在光照下呈现出更逼真的效果,我们需要为物体应用合适的材质。Three.js 提供了多种材质类型,适用于不同的光照效果。以下是几种常用的材质类型。
1.21 MeshBasicMaterial
这种材质不受光照影响,颜色和纹理将保持恒定。适用于没有光照需求的场景。
import { MeshBasicMaterial } from 'three';
const material = new MeshBasicMaterial({ color: 0xff0000 });
1.22 MeshLambertMaterial
MeshLambertMaterial 是一种基于漫反射的材质,能够响应光照并在表面产生阴影。适用于简单的光照场景。
import { MeshLambertMaterial } from 'three';
const material = new MeshLambertMaterial({ color: 0xff0000 });
1.23 MeshPhongMaterial
MeshPhongMaterial 是一种基于 Phong 着色模型的材质,能够响应光照并产生镜面反射。适用于表面光滑的物体。
import { MeshPhongMaterial } from 'three';
const material = new MeshPhongMaterial({ color: 0xff0000, specular: 0xffffff, shininess: 30 });
1.24 MeshStandardMaterial
MeshStandardMaterial 是一种基于 PBR(Physically Based Rendering)的材质,能够模拟复杂的光照效果,如金属、玻璃等。
import { MeshStandardMaterial } from 'three';
const material = new MeshStandardMaterial({ color: 0xff0000, roughness: 0
2. 阴影投影
在 Three.js 中,阴影对于创建逼真的场景至关重要。通过为场景添加阴影投影,我们可以为 3D 对象增加真实感和深度。本文将详细介绍如何在 Three.js 中使用阴影投影。
2.1 阴影支持
要在 Three.js 中使用阴影,首先需要确保渲染器支持阴影,并为光源启用阴影。然后,需要设置物体的 castShadow
和 receiveShadow
属性。
2.21 启用阴影支持
首先,在创建渲染器时启用阴影支持:
const renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
2.22 为光源启用阴影
要使光源能够产生阴影,需要为其启用阴影。以聚光灯为例:
const spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(0, 10, 0);
spotLight.castShadow = true;
spotLight.angle = Math.PI / 6;
spotLight.penumbra = 0.1;
spotLight.distance = 20;
spotLight.decay = 2;
scene.add(spotLight);
2.23 设置物体投射和接收阴影
要使物体能够投射阴影,需要为其设置 castShadow
属性。要使物体能够接收阴影,需要为其设置 receiveShadow
属性。
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.castShadow = true;
cube.receiveShadow = 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.receiveShadow = true;
plane.rotation.x = -Math.PI / 2;
plane.position.y = -1;
scene.add(plane);
现在,场景中的物体将会根据光源的位置和类型产生阴影效果。
2.2 调整阴影效果
在 Three.js 中,可以通过调整光源和渲染器的参数来优化阴影效果。
2.21 调整光源阴影参数
光源具有 shadow
属性,用于调整阴影的质量和范围。以下是一些常用的阴影参数设置:
-
shadow.mapSize
: 控制阴影贴图的大小。值越大,阴影质量越高,但计算成本也更高。通常设为 2 的次方值,如 512、1024 或 2048。 -
shadow.bias
: 用于修复阴影投射中的阴影锯齿状或漂浮阴影的问题。根据场景和光源类型,需要小心调整这个值,以避免产生不自然的阴影效果。
以下是一个调整聚光灯阴影参数的示例:
spotLight.shadow.mapSize.width = 1024;
spotLight.shadow.mapSize.height = 1024;
spotLight.shadow.bias = -0.001;
2.22 调整渲染器阴影类型
Three.js 提供了两种渲染器阴影类型:THREE.BasicShadowMap
和 THREE.PCFShadowMap
。THREE.BasicShadowMap
是简单的阴影效果,而 THREE.PCFShadowMap
提供了更柔和的阴影效果。根据需求选择合适的阴影类型:
renderer.shadowMap.type = THREE.PCFShadowMap;
2.23 使用自定义阴影贴图
在某些情况下,为了实现特定的阴影效果,可以考虑使用自定义阴影贴图。自定义阴影贴图可以让你更精确地控制阴影效果,但需要更高的技能水平和对 Three.js 的深入了解。
const customShadowTexture = new THREE.TextureLoader().load('path/to/shadow/texture.png');
const customShadowMaterial = new THREE.ShadowMaterial({ map: customShadowTexture });
const customShadowMesh = new THREE.Mesh(geometry, customShadowMaterial);
scene.add(customShadowMesh);