第五章“灯光照明 - 光照效果”是深入探讨Three.js中光照和阴影使用的章节。以下是包含平行光(DirectionalLight
)的详细教程和示例:
5.1 光照原理与模型
教程:
- 光照基础:光照是3D图形学中模拟现实世界光照效果的方法,它影响物体表面的视觉表现。
- 光照模型:学习Phong和Lambert着色模型,这些模型描述了光照如何与物体表面相互作用。
示例:
javascript
// 创建一个简单的材质并添加到几何体上
const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const geometry = new THREE.BoxGeometry(1, 1, 1);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
5.2 光源类型:环境光、点光源、聚光灯、平行光
教程:
- 环境光 (
THREE.AmbientLight
):提供无方向的光照,常用于场景的基本照明建议先阅读完文章,再查看 实例代码。 - 点光源 (
THREE.PointLight
):从一个点向所有方向发射光,具有衰减效果,可以产生阴影建议先阅读完文章,再查看 实例代码。 - 聚光灯 (
THREE.SpotLight
):从一个点沿特定方向发射光,具有光束和衰减效果建议先阅读完文章,再查看 实例代码。 - 平行光 (
THREE.DirectionalLight
):模拟来自遥远点的光,如太阳光线,常用于模拟日光效果。建议先阅读完文章,再查看 实例代码。
示例:
javascript
// 创建环境光
const ambientLight = new THREE.AmbientLight(0x404040, 0.5); // 柔和的灰色光
scene.add(ambientLight);
// 创建点光源
const pointLight = new THREE.PointLight(0xffffff, 2, 100);
pointLight.position.set(10, 20, 10);
scene.add(pointLight);
// 创建聚光灯
const spotLight = new THREE.SpotLight(0xffffff, 2);
spotLight.position.set(-10, 20, -10);
spotLight.angle = Math.PI / 4;
scene.add(spotLight);
// 创建平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 2, 4).normalize(); // 将位置向量标准化为方向向量
scene.add(directionalLight);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh;
- 有无光照对物体材质影响建议先阅读完文章,再查看 实例代码
- AmbientLight 环境光会【均匀】的照亮场景中的所有物体。建议先阅读完文章,再查看 实例代码
- pointLight 衰减效果建议先阅读完文章,再查看 实例代码
5.3 光照与阴影
教程:
- 阴影基础:学习如何使用光照产生阴影,以及阴影对场景真实感的影响。
- 阴影映射:了解阴影映射的工作原理和性能考虑。
环境光(AmbientLight):
- 环境光提供了一个场景中的基本光照,它没有方向,因此通常不会产生阴影。
点光源(PointLight):
- 点光源可以产生阴影,但需要设置
castShadow
属性为true
来启用阴影。点光源的阴影通常是圆形的,因为光源是从一个点向外发射光线。
- 点光源可以产生阴影,但需要设置
聚光灯(SpotLight):
- 聚光灯也可以产生阴影,同样需要设置
castShadow
属性为true
。聚光灯的阴影会根据光源的锥角和位置产生类似聚光灯效果的阴影。
- 聚光灯也可以产生阴影,同样需要设置
平行光(DirectionalLight):
- 平行光通常模拟来自无限远处的光源(如太阳),它也可以产生阴影,并且同样需要设置
castShadow
属性为true
。平行光产生的阴影通常更加均匀和广阔。
- 平行光通常模拟来自无限远处的光源(如太阳),它也可以产生阴影,并且同样需要设置
要启用阴影,还需要在场景中设置一个阴影映射技术,例如PCFShadowMap
(Percentage-Closer Filtering Shadow Map),并且可能需要调整光源的shadow.mapSize
属性来控制阴影的分辨率。此外,场景中的物体需要有对应的材质属性来接收阴影。
下面是一个简单的示例代码,展示如何在Three.js中设置光源以产生阴影:
javascript
// 创建一个场景
var scene = new THREE.Scene();
// 创建一个点光源,并启用阴影
var pointLight = new THREE.PointLight(0xffffff, 1, 100);
pointLight.position.set(5, 5, 5);
pointLight.castShadow = true; // 启用阴影
scene.add(pointLight);
// 创建一个聚光灯,并启用阴影
var spotLight = new THREE.SpotLight(0xffffff, 1);
spotLight.position.set(-5, 5, 5);
spotLight.castShadow = true; // 启用阴影
scene.add(spotLight);
// 创建一个平行光,并启用阴影
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(0, 1, 0);
directionalLight.castShadow = true; // 启用阴影
scene.add(directionalLight);
// 添加物体到场景中,并确保它们的材质可以接收阴影
// ...
示例:
javascript
// 为聚光灯和平行光启用阴影映射
spotLight.castShadow = true;
directionalLight.castShadow = true;
// 创建一个平面,用于接收阴影
const groundGeometry = new THREE.PlaneGeometry(50, 50, 1, 1);
const groundMaterial = new THREE.MeshPhongMaterial({ color: 0x999999 });
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
ground.rotation.x = -Math.PI / 2;
ground.receiveShadow = true; // 启用阴影接收
scene.add(ground);
// 添加一个能够投射阴影的立方体
const cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
const cubeMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.y = 8;
cube.castShadow = true; // 启用阴影投射
scene.add(cube);
// 配置阴影相机的属性
spotLight.shadow.camera.near = 1;
spotLight.shadow.camera.far = 50;
spotLight.shadow.bias = -0.0001;
- 第一件事是设置渲染器中的阴影属性
javascript
const renderer = new THREE.WebGLRenderer({ canvas });
renderer.shadowMap.enabled = true;
- 第二件事是设置光能投射阴影
javascript
const light = new THREE.DirectionalLight(color, intensity);
light.castShadow = true;
- 第三件事是在场景中的每个网格,我们都能设置它是否能投射阴影或被投射阴影。 这里我们只设置【地面】能被投射阴影,这样我们不需要关心地面投射阴影的问题
javascript
const mesh = new THREE.Mesh(planeGeo, planeMat);
mesh.receiveShadow = true;
- 第四件事是对于球体和立方体,我们需要设置他们都能投射阴影或者被投射阴影
javascript
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.castShadow = true;
mesh.receiveShadow = true;
5.4 高级光照技术
教程:
- 半球光 (
THREE.HemisphereLight
):模拟来自天空和地面的光照,适合户外场景。 - 面积光 (
THREE.RectAreaLight
):创建一个矩形区域的光源,用于产生柔和的光照效果。建议先阅读完文章,再查看 实例代码 - 光照贴图:使用光照贴图来模拟复杂的光照环境。
示例:
javascript
// 创建半球光
const hemisphereLight = new THREE.HemisphereLight(0x00aaff, 0xffaa00, 1);
scene.add(hemisphereLight);
// 注意:THREE.RectAreaLight 不是Three.js的标准部分,可能需要使用扩展库
总结
光照是3D场景中不可或缺的元素,它不仅影响场景的视觉效果,还能增强场景的深度和真实感。通过掌握不同类型的光源、阴影映射和高级光照技术,你可以创建出更加丰富和动态的3D场景。特别是平行光,它在模拟日光等远距离光源时非常有用。如果你需要更具体的帮助,如实现特定的光照效果或优化性能,请随时提问。