双光源
16 / 17
在简单球体上学习光照项(漫反射/高光/边缘光)。
多光源的原理很简单:对每盏灯分别计算漫反射,然后加权叠加。关键代码是:
下面拆解它的结构。
为什么要加权
现实中的光有强有弱。第一盏灯贡献 70%(0.7),第二盏贡献 50%(0.5)。如果两盏都是 1.0,正面受两盏灯照射时亮度会超出自然范围,产生过曝感。
权重让你可以设定主光(key light)和补光(fill light)的关系:主光更强,从正面照亮主要轮廓;补光较弱,从另一侧补足暗部细节。
两盏灯的方向
两盏灯从不同角度照射,球体表面的每一块区域都会同时受到来自两个方向的光照贡献。normalize 确保方向向量长度为 1,漫反射计算的结果才正确。
叠加公式
max(..., 0.0) 保证背光面贡献不会是负数(负数会让球体变暗,不符合物理)。两项直接相加,得到来自两盏灯的总漫反射量。
试着改一改
| 改动 | 效果 |
|---|---|
把 l1 权重 0.7 改为 0.3 | 两盏灯亮度趋于均衡 |
把 l2 方向改为 vec3(-0.6, 0.2, 0.6) | 两盏灯来自同侧,背面完全无光 |
| 再加一盏 l3,从正下方照射 | 产生三点光效果 |
| 给两盏灯添加不同颜色乘数 | 冷暖光对比效果 |
练习
练习代码中两盏灯的方向 l1、l2 已经定义好,但 diff 还只用了一盏灯。补全第二盏灯的漫反射项,将两项加权叠加,让球体出现双光源的受光效果。
答案解析
起始代码只有 diff = max(dot(n, l1), 0.0) * 0.7,球体只受一盏灯影响。右侧区域只能靠环境光显示,缺少层次感。
加上 + max(dot(n, l2), 0.0) * 0.5 后,第二盏灯从右侧补光,球体正面中心两灯叠加最亮,两侧各受一盏灯,背面接近黑色。权重 0.7 和 0.5 让主光和补光有明显区别。
试着给第二项再加一个颜色乘数,比如 * vec3(0.8, 0.6, 1.0),让补光带一点蓝紫色,制造冷暖对比。