高级 #graphics#lighting#shading

光照与着色模型

着色(Shading)计算每个像素的最终颜色——Phong 模型分解为环境光+漫反射+高光,Blinn-Phong 是更高效的变体。BRDF 描述材质对光的反射特性

💡 一个没有光照的 3D 世界——都是平的

没有光照,所有物体只有本身的颜色——看起来像一个扁平的世界。光照让物体有立体感:朝阳面亮、背阴面暗、高光点反射。

着色(Shading) = 计算每个像素的最终颜色。光照模型告诉你:给定光源、材质和观察角度——这个像素应该是什么颜色。


🔦 Phong 光照模型

Phong 把光照分解为三个独立的部分:

最终颜色 = 环境光 + 漫反射 + 高光(镜面反射)

① 环境光(Ambient)——最基础的均匀照明

没有直接光源时,房间也不是全黑的——光线经过多次反射均匀照亮了物体。

环境光 = Ka × Ia
(Ka:材质的反射系数,Ia:环境光强度)
比如:暗处也有 10% 的底色可见

② 漫反射(Diffuse)——粗糙表面的均匀反射

光线照到粗糙表面——向各个方向均匀反射,从任何角度看都一样亮。

关键:表面越正对光源越亮(兰伯特余弦定律)。

漫反射 = Kd × I × max(0, n·l)
n:表面法线方向
l:指向光源的方向
n·l = cos(θ):法线和光源方向的点积

当表面正对光源时(θ=0°):最亮
当表面和光源平行时(θ=90°):最暗

③ 高光(Specular)——光滑表面的镜面反射

光线照到光滑表面——在反射方向集中反射。从特定角度能看到”亮点”。

高光 = Ks × I × max(0, r·v)^p
r:反射向量
v:视线方向
p:高光指数——越大,高光点越小越亮
(塑料 p≈10,金属 p≈100+)

🆚 Blinn-Phong——更高效的改进

Blinn-Phong 用半程向量 h 代替反射向量 r:

h = (l + v) / |l + v|    — 半程向量(l 和 v 的中间方向)

Blinn-Phong 高光 = Ks × I × max(0, n·h)^p'

优势:计算量更小,效果接近——是 OpenGL 固定管线的默认光照模型。

Phong:需算 r(反射向量)
Blinn-Phong:只需算 h(l 和 v 加起来归一化)

🎨 着色频率——从粗糙到精细

方式方法效果性能
Flat Shading每三角形一个颜色块状感最快
Gouraud Shading每顶点算颜色,像素插值平滑但高光可能丢失
Phong Shading每像素插值法线再算光照最真实最慢
Flat:三角形面 {颜色=A的着色结果}
Gouraud:顶点 {颜色A, 颜色B} → 插值到像素
Phong:顶点 {法线A, 法线B} → 插值法线 → 每个像素算光照

📝 小结

概念一句话
环境光均匀背景照明——让暗处可见
漫反射粗糙表面——正对光源更亮(n·l)
高光光滑表面——特定角度反射亮点(h^n)
Blinn-Phong半程向量代替反射向量——更高效
Phong Shading每像素插值法线算光照——最真实

为什么先学这个? 理解了直接光照,接下来看间接光照——阴影与环境光遮蔽