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 已经设好了,当前代码可以正常运行,尝试把 shininess 从 32.0 改到不同值(如 4.0、64.0、256.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.0 到 256.0 可以模拟从橡皮到镜面的各种材质。
试着把 specularStrength 从 1.0 改为 0.3,看高光会变暗多少。