兰伯特光照模型完全解析:计算机图形学的第一束光


你在家里用手电筒照墙壁,发现一个有趣的现象:垂直照过去时光斑又小又亮,斜着照时却变得又大又暗。为什么?
答案藏在一个简单的余弦函数里——它就是计算机图形学中最基础的光照模型:兰伯特光照模型(Lambertian Reflectance)

什么是漫反射?为什么要关心它?

先从直觉开始。拿一张白纸,用手电筒从任意角度照它——无论你从哪个方向看,纸的亮度都是一样的。这是因为纸张表面在微观上是粗糙的,光线被均匀地反射到各个方向。这种反射就叫漫反射(Diffuse Reflection)
我们每天看到的绝大多数物体——墙壁、布料、纸张、磨砂塑料——其颜色都来自漫反射。所以,要渲染出真实的物体,首先得把漫反射算对。
💡
它的核心思想极其简单:表面越正对光源就越亮,越侧对光源就越暗。就这么回事。

核心原理:Lambert's Cosine Law

1760 年,德国数学家约翰·海因里希·兰伯特(Johann Heinrich Lambert)发表了一个影响深远的观察:
一个理想漫反射面元接收到的光能量,与光线方向和表面法线之间夹角的余弦成正比。
用数学语言表达就是:
逐项拆解:
符号
含义
取值范围
漫反射系数(材质颜色)
RGB 向量,如 (1.0, 0.5, 0.0)
光源强度
通常 (1.0, 1.0, 1.0)
表面法向量(单位向量)
长度 = 1
指向光源的方向向量(单位向量)
长度 = 1
点积(视角影响因子)
$costheta$,范围 [-1, 1]
背面截断
防止背光面发光
由于 都是单位向量,点积就是夹角余弦:
 
 
 
 
notion image
所以核心公式也可以写成:
📝
⚠️ 为什么用 max(0, ...)?因为当光线从物体背面射入时(), 为负值。如果不截断,背光面就会"发光",这显然不对。max(0, ...) 保证背光面为纯黑。

为什么角度越大越暗?三段类比让你秒懂

类比一:🌞 太阳晒皮肤

中午 12 点,太阳在头顶正上方(),你感觉最晒。到了傍晚,太阳斜射(),同样的阳光被摊薄到更大的受热面积上,就没那么晒了。
这就是 在物理世界中的直观体现——能量守恒。

类比二:🔦 手电筒照墙

  • 垂直照墙 → 光斑面积小,能量集中 → 亮
  • 斜着照墙 → 光斑被拉长,能量分散 → 暗
💡
一句话总结完全文:表面越正对光源就越亮,越侧对光源就越暗。这就是 的全部含义。

典型数值速查

亮度
场景
1.0
💡 最亮
正对光源
0.866
🔆 很亮
稍微倾斜
0.707
🔅 中等
常见角度
0.5
🌗 半亮
明显变暗
0.0
🌑 无光
平行于表面
负值
⬛ 全黑
背面

实战:GLSL 代码实现

理论说完了,来看能跑的代码。这是 OpenGL/WebGL 中完整的片段着色器:
⚠️
三大常见陷阱:1) 法向量忘记归一化 → 计算错误 2) 法向量与顶点世界坐标不在同一坐标系 → 光照错位 3) 忘记 → 背面发光

优缺点分析

✅ 优点

  • 计算极简:一次点积 + 一个 max,GPU 上效率极高
  • 各向同性:结果与观察方向无关,不闪烁
  • 物理含义清晰:能量守恒的完美数学体现

❌ 缺点

  • 没有高光:物体像磨砂塑料,缺乏光泽
  • 没有环境光:背光面全黑,需配合 ambient 项
  • 过于理想化:真实材质几乎都有镜面成分

进阶:与其他光照模型对比

模型
漫反射
高光
计算量
适用场景
Lambert
⭐ 极低
粗糙表面、环境光照
Phong
⭐⭐⭐ 中
光滑材质、早期游戏
Blinn-Phong
⭐⭐ 低
现代实时渲染主流
  • Phong 模型:在兰伯特基础上增加了镜面高光计算,用视线方向与反射光线的点积生成高光
  • Blinn-Phong 模型:用半程向量()代替反射向量计算,更高效、高光更柔和,是现代最常用的光照模型之一
📝
延伸思考:在 PBR(基于物理的渲染)中,漫反射项已经不再简单地使用兰伯特模型了——迪士尼原则的 BRDF 使用 Schlick 近似处理 Fresnel 效应。但无论 PBR 如何演进,兰伯特模型作为漫反射的"第一性原理",始终是理解所有光照模型的基石。

总结

核心要点
一句话
物理本质
粗糙表面的均匀漫反射
数学公式
直觉理解
正对光源亮,侧对光源暗
代码实现
一次 normalize + dot + max
进阶方向
Phong → Blinn-Phong → PBR
理解兰伯特光照模型,就等于理解了图形学光照的半壁江山。剩下的,不过是在这个简单框架上不断叠加新效果。

非真实感渲染(NPR)管线拆解:从卡通着色到风格化笔触 Transformer 大语言模型运作原理解析:从零拆解 AI 的「基础底座」
Loading...