高光控制
15 / 17
在简单球体上学习光照项(漫反射/高光/边缘光)。
控制高光的大小和锐利度,核心就是这一行:
下面拆解它。
shininess 是什么
shininess 是高光的"光滑度"参数,传给 pow 的指数。它决定高光的大小和锐利程度:
shininess = 4→ 高光很大很柔,像哑光橡皮shininess = 16→ 中等,像塑料shininess = 64→ 小而亮,像金属漆shininess = 256→ 极小极亮,像镜面或玻璃
指数越大,只有非常接近"完美反射角"的像素才保留亮度,高光点变得又小又集中。
半向量 hV 是什么
这里用的是 Blinn-Phong 改进版,不直接用反射向量 r,而是用光线方向 l 和视线方向 v 的中间向量:
把 l 和 v 加在一起再归一化,得到一个"夹在中间"的方向。然后看法线 n 和 hV 有多对齐,越对齐高光越亮。
Blinn-Phong 比 Phong 计算更快,而且当视角接近掠射角时表现更稳定。
试着改一改
| 改动 | 效果 |
|---|---|
shininess = 16.0 改为 4.0 | 高光很大,表面像橡皮 |
shininess = 16.0 改为 64.0 | 高光变小,表面更光滑 |
* spec * 0.6 的 0.6 改为 1.5 | 高光亮度增加,可能过曝 |
练习
当前练习区 spec = 0.0,没有高光,补全 TODO,用 hV 和 shininess 计算出正确的高光值。
答案解析
初始状态:spec = 0.0,球体只有漫反射。
改动:用 dot(n, hV) 计算法线和半向量的对齐程度,再用 pow(..., shininess) 把它集中成一个高光点。shininess = 16.0 对应中等光滑的材质效果。
试着把 shininess 改成 2.0,看看高光会扩散到多大范围。