Lambert 光照(球)
8 / 17
用估计法线实现 Lambert 漫反射,为球体着色。
给球体加上最基础的漫反射光照,核心就是这一行:
下面拆解它。
漫反射是什么
漫反射是最简单的光照模型,模拟粗糙表面把光均匀散射到各个方向的效果。你看到的木头、石头、布料,大部分都是这种反光方式。
效果很直观:正对着光的地方最亮,侧面变暗,背对光的地方完全黑。
dot(n, lightDir) 是什么意思
dot(n, lightDir) 计算法线方向和光线方向有多对齐:
- 完全一致(法线正对光源)→ 1.0,即 100% 亮度
- 垂直(法线与光线成 90°)→ 0.0,即 0%
- 背向光源 → 负数,截断成 0(不可能比黑更暗)
max(..., 0.0) 的作用是把负数截断为 0,确保背光面不会出现负颜色。
亮度合成
代码里用了一个混合公式:
0.15 是底色(防止完全黑透),0.85 * diff 是光照强度。两者加起来,亮部接近 100%、暗部保留 15% 的基础亮度。
试着改一改
| 改动 | 效果 |
|---|---|
0.15 改为 0.4 | 暗部更亮,对比度降低 |
0.85 改为 1.5 | 亮部过曝,球体高光区变白 |
lightDir 的 x 分量从 -0.4 改为 0.8 | 光源从左移到右,球体明暗翻转 |
练习
当前练习区的球体是一片均匀的暗色(diff = 0.0),补全 TODO 行,计算正确的漫反射值让球体呈现出明暗渐变。
答案解析
初始状态:diff 固定为 0.0,球体只有 base * 0.15 的暗底色,看起来是一团深色圆。
改动:把 dot(n, lightDir) 的结果用 max(..., 0.0) 截断为非负数。法线和光方向越对齐,diff 越接近 1.0,对应的像素就越亮。
试着把 max(dot(n, lightDir), 0.0) 改成 dot(n, lightDir) * 0.5 + 0.5,看看暗部会发生什么变化。