光照模型的核心是计算物体表面上每个点的颜色(即最终呈现在屏幕上的像素颜色)。这个过程结合了物体材质属性(颜色、反光度、粗糙度等)和场景中的光照信息。Three.js 的实现遵循了经典的计算机图形学光照模型。
我们可以从三个层面来理解:
Three.js 的光照系统主要基于经典的 Phong 光照模型(或更现代的 Blinn-Phong 变种)。它将最终的光照效果分解为几个独立分量的叠加:
环境光(Ambient):
概念:模拟场景中来自所有方向的、均匀的漫反射光。可以理解为“背景光”或“间接光”的简化。
计算:非常简单。最终颜色 += 物体材质颜色 × 环境光颜色 × 环境光强度。
特点:没有方向,没有位置,整个场景均匀受光。单独使用会使物体看起来像一个二维剪影。
漫反射光(Diffuse):
概念:模拟光线照射到粗糙表面后,向各个方向均匀散射的现象。这是物体呈现“固有色”的主要原因。
计算:遵循兰伯特余弦定律。光照强度与光线方向向量(L)和表面法线向量(N)的夹角的余弦值成正比。即 强度 = max(cos(θ), 0) = max(dot(N, L), 0)。
特点:与观察者视角无关,只取决于光线和表面的夹角。它产生了基本的明暗过渡。
高光反射(Specular):
概念:模拟光线在光滑表面发生的镜面反射,形成明亮的“高光点”。
计算(Phong模型):
计算光线的反射向量 R。
计算观察者视线向量 V 与反射向量 R 的夹角。
强度 = pow(max(dot(V, R), 0), 光泽度)。
计算光线方向 L 和视线方向 V 的中间向量(半角向量)H。
强度 = pow(max(dot(N, H), 0), 光泽度)。
光泽度(shininess)值越高,高光点越小、越锐利。最终Phong模型颜色(简化版):
text
颜色 = 环境项 +
漫反射项 * 材质漫反射色 * 光漫反射色 +
高光项 * 材质高光色 * 光高光色
Three.js 提供了多种光源,它们定义了光线在空间中的分布方式,并为上述模型提供参数(如光的颜色、方向、位置)。

材质定义了表面对光照的“反应规则”。不同材质使用不同复杂度的着色器来实现光照模型。

选择材质:
追求真实感,首选 MeshStandardMaterial 或 MeshPhysicalMaterial。
需要高性能或风格化效果,可选 MeshLambertMaterial 或 MeshPhongMaterial。
完全不需要光照,用 MeshBasicMaterial。
组合光源:
典型的室内布光:DirectionalLight(主光/太阳)+ PointLight/RectAreaLight(补光/灯具)+ AmbientLight/HemisphereLight(环境补光)。
避免仅使用 AmbientLight,它会令场景失去立体感。
性能考量:
光源数量越多,性能开销越大(尤其是阴影计算)。
使用 distance 和 decay 属性限制点光源和聚光灯的影响范围,可以优化性能。
阴影:
阴影是独立但相关的系统。只有 DirectionalLight、PointLight、SpotLight 能产生阴影。
需要为光源(.castShadow = true)、可投射阴影的物体(.castShadow = true)和接收阴影的物体(.receiveShadow = true)分别开启设置。
javascript
// 1. 创建场景、相机、渲染器(略)
// 2. 创建PBR材质
const material = new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.5, // 粗糙度 (0: 非常光滑, 1: 非常粗糙)
metalness: 0.8 // 金属度 (0: 非金属如塑料, 1: 金属如铜铁)
});
// 3. 创建几何体并应用材质
const sphere = new THREE.Mesh(new THREE.SphereGeometry(1, 32, 32), material);
scene.add(sphere);
// 4. 添加组合光源
// 主方向光(模拟太阳)
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(5, 5, 5);
scene.add(directionalLight);
// 柔和的天空环境光
const hemisphereLight = new THREE.HemisphereLight(0x87ceeb, 0x8b4513, 0.3);
scene.add(hemisphereLight);
// 一个补光的点光源
const pointLight = new THREE.PointLight(0xffaa33, 0.5, 10);
pointLight.position.set(-3, 2, 1);
scene.add(pointLight);
理解 Three.js 光照模型的关键在于:
理论基础:掌握 环境光、漫反射、高光 三个核心分量。
实践组合:根据场景需求,选择合适的材质(特别是PBR材质) 并混合使用多种类型的光源。
迭代调试:光照是艺术和技术的结合,需要不断调整光源的位置、颜色、强度以及材质的参数(如粗糙度、金属度)来达到理想效果。