#sec-3-1
Geometry · Normal
法向量N:给表面一个局部朝向
曲面在任意一点处的切平面垂线称为该点的法向量(Normal),是光照计算的第一基石:
① 几何朝向 (\(\hat{\mathbf{n}} \perp \text{切平面}\))
垂直于局部表面切平面,定义物体表面的“正面”与“朝外方向”。
② 顶点逆时针绕序 (CCW)
右手定则:顶点按逆时针排布时,叉乘 \((B-A)\times(C-A)\) 天然指向外侧。
③ 严格单位化 (\(\|\hat{\mathbf{n}}\| = 1\))
归一化长度,确保后续点乘纯粹反映角度余弦,不受三角形边长尺寸干扰。
#sec-3-1-fig
Old Asset · Normals
图解法线:面法线与顶点法线为何不同?
同一折面/曲面上的法线可以按面定义,也可按顶点进行平滑处理;光照公式需要的是当前着色点的单位法线。
看图提问:哪些法线对齐同一三角面?哪些随曲面位置平滑改变?法线方向改变如何影响
dot(N,L)?
#sec-3-2
Math · Dot Product
点积:把两个三维方向变成夹角余弦
\(\hat{\mathbf{n}}\cdot\hat{\mathbf{l}}=\cos \theta\quad
(\hat{\mathbf{n}},\hat{\mathbf{l}} \text{ 均为单位向量})\)
正对入射 (\( \theta=0^\circ\))
\(\cos 0^\circ = 1.0\)
光线垂直直击表面,接受能量密度最大。
倾斜入射 (\(0^\circ< \theta<90^\circ\))
\(0 < \cos \theta < 1.0\)
光能被倾斜表面稀释分摊,亮度平滑降低。
背光照射 (\( \theta\ge 90^\circ\))
\(\cos \theta \le 0\)
光线位于切平面下方,物理上无法照亮表面。
方向定义守则:入射向量 \(\hat{\mathbf{l}}\)
约定由表面点指向光源,确保正对光源时光线与法向量夹角为 0°。
#sec-3-2-fig
New Figure · Dot Product
一张图读懂 N·L = cosθ 的三个角度
固定光照强度,仅改变光线与法线夹角,观察同一面积表面如何从亮变暗,最后进入背光区。
公式读图:θ从 0° 增大到 90°,漫反射由1减至0;超过90°时
max(0, dot(N,L)) 截断为0。
#sec-3-2-demo
Interactive Demo · Dot Product
D06-02 · 法向量与漫反射显微镜
D06-02 · 教学实验台
SVG + 实时点积计算 + 朗伯明暗渲染
法向量与漫反射显微镜
直观拖动单位法线 \(\mathbf{n}\) 与光线向量 \(\mathbf{l}\),实时探究夹角
\(\theta\)、点积 \(\mathbf{n}\cdot\mathbf{l}\) 与表面朗伯明暗的动态数学映射。
🔹 双操作模式:支持“固定 N 拖动 L”与“固定 L 改变表面朝向 N”
🔹 实时数值监控:毫秒级输出
\(\theta\)、\(\mathbf{n}\cdot\mathbf{l}\) 与非负截断 \(\max(0,
\mathbf{n}\cdot\mathbf{l})\)
🔹 背光物理截断:当 \(\theta \ge 90^\circ\)
时清晰显示表面背侧区域与归零保护
课堂观察任务
3 min
带着问题观察与验证
-
0° 正射验证:将 L 对齐 N(\(\theta =
0^\circ\)),观察点积是否为 1.0,漫反射亮度是否达到峰值。
-
60° 余弦减半:拖动到 \(\theta = 60^\circ\),验证 \(\cos
60^\circ = 0.5\),明度恰好减半。
-
90° 临界切光:拖到 \(\theta =
90^\circ\),观察点积是否恰好归零。
-
>90° 背光截断:拖入背光区(如
120°),观察点积出现负值时,\(\max(0, \dots)\) 如何将实际漫反射保护性截断为
0。
💡 重点理解:点积直接量化了光线与表面朝向的几何投影关系,截断保护排除了背光负值。
#sec-3-3
Geometry · View & Reflection
视线向量V与理想反射向量R
要计算高光,除了法向量 \(\hat{\mathbf{n}}\) 和光线
\(\hat{\mathbf{l}}\),还必须引入视点与反射轴:
视线向量 \(\mathbf{v}\) (View Vector)
\(\hat{\mathbf{v}} = \operatorname{normalize}( \text{Eye} - P)\)
由表面点指向相机视点位置,表示观察者的视线朝向。对应第五章中的相机坐标系 Eye
位置。
反射向量 \(\mathbf{r}\) (Reflection Vector)
\(\hat{\mathbf{r}} = 2(\hat{\mathbf{n}}\cdot\hat{\mathbf{l}})\hat{\mathbf{n}} -
\hat{\mathbf{l}}\)
入射光线关于法向量 \(\mathbf{n}\)
的理想镜面反射方向。符合光学反射定律:入射角等于反射角,且共面。
四大单位向量归位:法向量 \(\hat{\mathbf{n}}\)、光线 \(\hat{\mathbf{l}}\)、反射线
\(\hat{\mathbf{r}}\)、视线 \(\hat{\mathbf{v}}\) 构成了局部着色的全部几何骨架!
#sec-3-3-fig
Reflection & Shading Geometry · Vectors N, L, V, R
图解 R 与 V:入射角=反射角
反射向量 R 由光源方向 L 和法线 N 决定;当视线 V 接近 R 时才可能出现强高光。
对图识向量:指向光源的是 \(\hat{\mathbf{l}}\);指向相机的是
\(\hat{\mathbf{v}}\);\(\hat{\mathbf{r}}\) 是镜面反射方向;\(\hat{\mathbf{v}}\) 与
\(\hat{\mathbf{r}}\) 的夹角记作 \(\alpha\)。
#sec-4-1
Lambert · Physical Intuition
定律一 · Lambert 漫反射:光能量的几何分摊
粗糙微观表面将光向全半球空间各向同性散射;接收到的光通量取决于表面受光面积:
垂直入射 (\( \theta=0^\circ\))
光束截面完全落入表面最小区域 \(A\),单位面积接收到的能量密度最大,表面最明亮。
倾斜入射 (\( \theta>0^\circ\))
相同能量的光束被拉长铺展到 \(A/\cos \theta\) 的更大面积上,单位面积光通量降低为
\(\cos \theta\) 倍。
理想漫反射体的出射辐射率与出射角度无关,而接收辐射度正比于 \(\cos \theta\)。
#sec-4-1-fig
Figure R06-04 · Lambert Projection
为什么照射越斜越暗?看光束投影面积
同宽、同能量的光束垂直照射时覆盖面积小;倾斜照射时覆盖面积变大,单位面积分得的能量变少。
量化关系:照射面积变为
\(A/\cos\theta\),单位面积照度变为原来的 \(\cos\theta\) 倍。
#sec-4-2
Formula · Diffuse
Lambert 余弦定律计算公式
\(I_d = k_d I_L \max(0, \hat{\mathbf{n}}\cdot\hat{\mathbf{l}})\)
漫反射系数 \(k_d\)
\(k_d \in [0,
1]\),代表材质对入射光的漫散射反射率,在彩色着色中对应物体固有色(如红球
\(k_d=(0.8,0.1,0.1)\))。
光源强度 \(I_L\)
入射光的辐射强度与冷暖颜色(RGB 能量向量)。
非负截断 \(\max(0, \dots)\)
背光面夹角 \( \theta > 90^\circ\) 时点积为负,强制截断为
0,防止物理荒谬的“负亮度吸光”。
#sec-4-3
Key Property · View Independence
漫反射的核心特征:视点无关性
为什么公式 \(I_d = k_d I_L \max(0, \hat{\mathbf{n}}\cdot\hat{\mathbf{l}})\)
中完全没有视线向量 \(\mathbf{v}\)?
朗伯辐射特性
微观表面各向同性散射,单位立体角的发光强度满足朗伯余弦;而人眼透视投影视网膜面积也满足同一余弦投影,两者恰好精确抵消!
渲染几何结论
漫反射表面的观测亮度与相机位置无关!
无论观察者站在哪里看,同一个表面点的漫反射明暗完全恒定。
漫反射塑造了物体稳定的“体积感与空间形体”——这是表面明暗层次与立体感的重要来源。
#sec-4-3-fig
Figure R06-09 · Diffuse Invariance
换相机不换漫反射:视点无关的几何证据
保持 P、N、L、材质和光源固定,仅将相机从 V₁ 移到 V₂;Lambert 漫反射项中没有 V。
关键结论:改变观察者方向不会改变同一表面点的 Lambert
出射辐射亮度;但其屏幕投影面积可以变化。
#sec-5-1
Specular · Physical Intuition
定律二 · Phong 镜面反射:方向性聚拢高光
光滑表面像一面微型镜子,将光主要沿理想反射方向 \(\hat{\mathbf{r}}\) 聚焦出射:
出射能量集中在以 \(\hat{\mathbf{r}}\) 为中心的圆锥体内;视线 \(\hat{\mathbf{v}}\) 与
\(\hat{\mathbf{r}}\) 越接近,捕捉到的高光越耀眼。
#sec-5-2
Formula · Specular
Phong 镜面反射公式与高光指数
\(I_s = k_s I_L [\max(0, \hat{\mathbf{r}}\cdot\hat{\mathbf{v}})]^n = k_s I_L
\cos^n\alpha\)
镜面反射系数 \(k_s\)
\(k_s \in [0,
1]\),控制高光的整体明度与反光率;在纯塑料中通常反射白光,在金属中带金属固有色。
视线夹角余弦 \(\hat{\mathbf{r}}\cdot\hat{\mathbf{v}}\)
\(\cos\alpha\),度量视线是否正对反射方向;只有当 \(\alpha < 90^\circ\)
且表面正对光照时有效。
高光指数 \(n\) (Shininess)
\(n \in [1, 256]\),通过高次幂使余弦急剧衰减;\(n\) 越大,高光斑越小越聚拢、材质越光滑镜面。
#sec-5-2-fig
Old Assets · Shininess
从三张图观察指数 n 如何压缩高光
固定物体与相机位置,只增大 Phong 指数 n;注意高光的明亮核心逐渐变窄。
对照公式:当
cosα=0.9,\(0.9^1=0.9\)、\(0.9^{32}\approx0.034\)、\(0.9^{128}\approx1.4\times10^{-6}\)。
#sec-5-3
Key Property · View Dependence
镜面高光的核心特征:视点强相关性
高光强度的计算公式必须由视线向量 \(\mathbf{v}\) 直接主导:
视角敏感性
当观察者在三维场景中走动时,\(\hat{\mathbf{r}}\cdot\hat{\mathbf{v}}\)
夹角随视点动态变化,高光光斑会在物体表面发生位移、拉伸或消失。
质感暗示性
漫反射只交代“这是什么颜色”,而高光形态直接向人脑传递材质的光滑度、潮湿感或金属质感(如油画中的高光点睛之笔)。
背光条件保护:若 \(\hat{\mathbf{n}}\cdot\hat{\mathbf{l}} \le
0\)(处于背光面),无论 \(\hat{\mathbf{r}}\cdot\hat{\mathbf{v}}\)
结果如何,都不产生镜面高光!
#sec-5-3-fig
Figure R06-10 · Specular View
移动视点:R 固定,R·V 却在变化
同一光源和同一表面点决定一条不变的理想反射轴
R;移动相机时,只有接近该轴的观察者看见强高光。
对照漫反射:换 V,N·L 不变;但
R·V 改变,高光强度随之改变。
#sec-6-1
Core Contrast · Two Laws
两大反射定律全景对比
漫反射与镜面反射并列构成了局部光照的核心双翼:
| 物理与计算维度 |
Lambert 漫反射定律 |
Phong 镜面反射定律 |
|
微观物理成因
|
表面微观凹凸粗糙,光线深入后多重散射
|
表面微观平整光滑,光线在分界面定向镜面反射
|
|
参与几何向量
|
法向量 \(\hat{\mathbf{n}}\)、入射向量 \(\hat{\mathbf{l}}\)
|
法向量 \(\hat{\mathbf{n}}\)、入射向量 \(\hat{\mathbf{l}}\)、反射
\(\hat{\mathbf{r}}\)、视线 \(\hat{\mathbf{v}}\)
|
|
视点依赖性
|
视点无关(无论站在哪看都一样亮)
|
视点强相关(视线对准反射方向才见高光)
|
|
视觉教学作用
|
塑造形体立体轮廓、明暗交界线与固有色
|
塑造表面光滑度、光泽耀斑与湿润/金属质感
|
只要把两个分量相加,表面就同时具备了“立体感”与“光泽感”!
#sec-6-1-fig
Old Assets · Component Contrast
两图并排:只有漫反射 vs 只有镜面高光
同一几何体在不同反射项下呈现不同外观:漫反射负责连续明暗,高光负责视点相关亮斑。
快速辨识:左图主导体积明暗,右图显示集中亮斑;二者合成即可同时表达形体与光泽。
#sec-6-2
WebGL2 · GLSL Implementation
片元着色器中的向量点乘与计算
#version 300 es
precision highp float;
in vec3 vNormal;
in vec3 vFragPos;
uniform vec3 uLightPos; // 光源世界位置
uniform vec3 uViewPos; // 相机 Eye 世界位置
uniform vec3 uKd, uKs; // 材质漫反射与镜面反射系数
uniform float uShininess; // 高光指数 n
out vec4 fragColor;
void main() {
vec3 N = normalize(vNormal);
vec3 L = normalize(uLightPos - vFragPos);
vec3 V = normalize(uViewPos - vFragPos);
vec3 R = reflect(-L, N); // GLSL内置反射函数,注意-L
// 1. 漫反射计算
float diff = max(dot(N, L), 0.0);
vec3 diffuse = uKd * diff;
// 2. 镜面反射计算(带背光保护)
float spec = (diff > 0.0) ? pow(max(dot(R, V), 0.0), uShininess) : 0.0;
vec3 specular = uKs * spec;
fragColor = vec4(diffuse + specular, 1.0);
}
工程细节:GLSL 的
reflect(I, N) 中第一个参数是“从光源指向表面的入射向量”,因此传入
-L。
#sec-6-3
AI Collaboration · Verify
AI 给出一段光照代码,怎样核验?
AI 助手生成了一段光照着色器代码,请作为专业图形工程师对其进行审查:
核验点一 · 向量方向与归一化
① 插值后的 vNormal 是否在片元着色器重新
normalize?
② 传入 reflect 的是 L 还是
-L?
核验点二 · 背光面高光泄漏
① 漫反射是否有 max(dot(N,L), 0.0) 截断?
② 背光面(dot(N,L) <= 0)时是否错误地计算了高光?
专业审查规范:方向统一 $\rightarrow$ 单位化 $\rightarrow$ 非负截断 $\rightarrow$
背光保护。