Phong光照模型

9 / 17
实现基础的Phong光照模型,模拟物体表面的环境光、漫反射和镜面高光效果。

把环境光、漫反射、高光三项合并成一个完整的光照函数,核心是这段代码:

下面拆解它。


Phong 模型的三个组成部分

Phong 是最经典的实时光照模型,把光照拆成三项分别计算再相加:

环境光(ambient):一个固定的基础亮度,不依赖方向,防止背光面完全黑。系数 0.2 意味着物体至少有 20% 的亮度。

漫反射(diffuse):粗糙表面的均匀散射,max(dot(normal, lightDir), 0.0) 让朝向光的地方亮、背向光的地方暗。

高光(specular):光滑面的镜面反射,pow(max(dot(viewDir, reflectDir), 0.0), shininess) 在反射光对着眼睛的地方产生一个亮点。shininess 越大,亮点越小越锐。


动态光源

这个例子里光源在随时间绕球体旋转:

光方向每帧都在变,所以高光点、明暗交界线都随之移动。


试着改一改

改动效果
shininess = 32.0 改为 8.0高光变大变柔
shininess = 32.0 改为 128.0高光变成小亮点
ambientStrength = 0.2 改为 0.05暗部更暗,对比更强
objectColor 改为 vec3(0.9, 0.5, 0.1)球体变成橙色材质

练习

练习区的 shininess 已经设好了,当前代码可以正常运行,尝试把 shininess32.0 改到不同值(如 4.064.0256.0),观察高光随之如何变化。

答案解析

Phong 模型的完整合并:

三项分别计算:

  • ambient = 0.2 * vec3(1.0) — 固定 20% 白光
  • diffuse = max(dot(normal, lightDir), 0.0) * vec3(1.0) — 方向相关的漫射
  • specular = pow(max(dot(viewDir, reflectDir), 0.0), shininess) * vec3(1.0) — 高光

shininess = 32.0 是一个中等偏光滑的初始值,对应类似喷漆表面的效果。从 4.0256.0 可以模拟从橡皮到镜面的各种材质。

试着把 specularStrength1.0 改为 0.3,看高光会变暗多少。

GLSL 代码编辑器

正确代码预览

当前代码预览