Three.js 光照系统进阶指南 —— 打造光明的舞台

"世界并不黑暗,只是你没打光。" ------ 一个没有灯光的 Three.js 场景


一、引子:没有光,何来三维世界?

在现实世界中,如果没有光,你什么也看不到。在虚拟的 3D 世界里,这道理同样成立。

在 Three.js 里,光照系统就像舞台剧的灯光导演: 你要为演员(模型)打光、为情绪渲染氛围、为观众(用户)展现细节。

今天我们将穿越照明的五重境界,从平光到物理真实,从基础到炫技,用代码和底层原理照亮你三维世界的每一寸角落。


二、照明五宗"光":谁才是舞台上的主角?

让我们先熟悉一下 Three.js 中的光照种类(就像认识一支光影剧团):

1️⃣ AmbientLight - 环境光

"我负责让世界不至于一片漆黑。"

  • 整个场景平均照亮,无方向、无阴影
  • 没有立体感,但是友好的基础照明
js 复制代码
const ambient = new THREE.AmbientLight(0xffffff, 0.3)
scene.add(ambient)

2️⃣ DirectionalLight - 平行光(太阳来了)

"我来自天外,但照得你头皮发烫。"

  • 类似太阳光,照射方向固定,光线平行
  • 支持阴影,适合大范围、清晰的影子效果
js 复制代码
const sun = new THREE.DirectionalLight(0xffffff, 1)
sun.position.set(10, 10, 10)
sun.castShadow = true
scene.add(sun)

🌞 实战技巧 :使用 light.target 指定照射目标(比如一只逃跑的老鼠)。


3️⃣ PointLight - 点光源(灯泡的亲戚)

"我是一颗孤独的光点,温暖着周围。"

  • 从一个点向四周发射光线,类似灯泡或法球
  • 有距离衰减,越远越暗
  • 可投射阴影,但要小心性能
js 复制代码
const bulb = new THREE.PointLight(0xffaa00, 1, 100)
bulb.position.set(0, 10, 0)
scene.add(bulb)

💡 小技巧 :使用 light.decay 控制真实感衰减(需配合 physicallyCorrectLights = true)。


4️⃣ SpotLight - 聚光灯(舞台最强气氛组)

"只照我想照的人。"

  • 有方向、有锥角、有阴影
  • 可用于手电筒、聚光舞台等效果
js 复制代码
const spotlight = new THREE.SpotLight(0xffffff, 1)
spotlight.position.set(5, 10, 5)
spotlight.angle = Math.PI / 6 // 控制锥角大小
spotlight.castShadow = true
scene.add(spotlight)

🎯 推荐搭配 :使用 spotLightHelper 查看照明区域。


5️⃣ RectAreaLight - 面光源(广告灯箱专用)

"我不是点,而是一整片柔和的光。"

  • 真实、柔和,适合室内灯带、面板灯
  • 只能影响 MeshStandardMaterialMeshPhysicalMaterial
  • 不支持阴影
js 复制代码
const rectLight = new THREE.RectAreaLight(0xffffff, 5, 4, 2)
rectLight.position.set(0, 5, 0)
rectLight.lookAt(0, 0, 0)
scene.add(rectLight)

📦 记得引入RectAreaLightUniformsLib.init() 初始化支持。


三、光照原理小课堂(不讲公式,只讲感情)

光照计算三大成分:

  1. 环境光(Ambient):统一底色,就像天很亮的时候,看哪里都亮。
  2. 漫反射(Diffuse):表面朝向光源的部分亮,背光部分暗,给模型立体感。
  3. 镜面反射(Specular):表面越光滑,越容易出现高光(比如光照打在油脸上...)。

这些原理被集成在材质中:

js 复制代码
const material = new THREE.MeshStandardMaterial({
  color: 0x6699ff,
  roughness: 0.5,  // 越小越光滑
  metalness: 0.3   // 金属感
})

🎨 你选择的材质决定了光照是否"入戏"! MeshBasicMaterial:不吃光 MeshStandardMaterial:吃光还懂物理


四、阴影的真相:不是谁都能投影

要开启阴影系统,有三件事必须到位:

js 复制代码
renderer.shadowMap.enabled = true
light.castShadow = true
mesh.castShadow = true
floor.receiveShadow = true

⚠️ 记住:

  • 光源必须支持阴影(例如 DirectionalLight
  • 对象必须**"投影"和"接收"**
  • 材质不能是基础材质(MeshBasicMaterial 不会管光)

五、高级技巧锦囊 🌟

1. 使用 physicallyCorrectLights 更真实

js 复制代码
renderer.physicallyCorrectLights = true

这会启用真实世界的光照衰减,让 intensity 变得更有物理意义。你会发现:

  • 聚光灯不再无敌
  • distancedecay 开始发挥作用

2. 动态灯光:为场景注入灵魂

js 复制代码
function animate() {
  requestAnimationFrame(animate)
  pointLight.position.x = Math.sin(Date.now() * 0.001) * 5
  renderer.render(scene, camera)
}

一个会跳舞的光源 = 一个有灵魂的场景 ✨


3. 视觉调试助手:让光照不再神秘

js 复制代码
scene.add(new THREE.DirectionalLightHelper(directionalLight, 5))
scene.add(new THREE.CameraHelper(directionalLight.shadow.camera))

六、结语:掌控光,就掌控了舞台

Three.js 的光照系统并非简单的开关,它是一套模拟真实世界光影互动的复杂系统。

而你,作为光的主宰者,要做到:

  • 知道用什么灯打什么光
  • 用材质配合光线表达情绪
  • 在性能和视觉之间取得平衡

"你无法创造真实的世界,但你可以让虚拟世界更接近真实。"


✨ 延伸阅读与练习:

  • 🔬 使用 MeshPhysicalMaterial 实现玻璃与反射
  • 🌄 配合环境贴图与光探针实现全局光照
  • 🔧 自定义光照 Shader:打造属于你的特效光(Volumetric God Rays)

相关推荐
崔庆才丨静觅4 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60615 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了5 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅5 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅6 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅6 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊6 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax