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,看看暗部会发生什么变化。

GLSL 代码编辑器

正确代码预览

当前代码预览