返回首页

Shader 101-03 - Lighting

基础光照模型

Lambertian reflectance

兰伯特光照模型(Lambertian Reflectance Model)是计算机图形学中最基础的漫反射光照模型,由18世纪科学家约翰·海因里希·兰伯特(Johann Heinrich Lambert)提出。它描述了理想漫反射表面(如粗糙的石膏、纸张)的光照行为,其核心特点是:光线在所有方向均匀散射,观察角度不影响亮度。

img

以下是一个简化的公式,只考虑光照的反射。

Idiffuse=max(0,nl)IlightI_{diffuse} = max(0, n \cdot l) \cdot I_{light}
  • nn : 表面法向量(单位向量)
  • ll : 光源方向(单位向量)
  • IlightI_{light} : 光源强度

完整的公式需要加上物理材质本身的颜色,公式如下所示。

Idiffuse=kdmax(0,nl)IlightI_{diffuse} = k_d \cdot max(0, n \cdot l) \cdot I_{light}
  • kdk_d : 物体漫反射颜色(材质颜色)

kdk_d 表示物体表面对不同波长光线的反射率(例如,红色物体反射更多红光),若省略 kdk_d,物体将完全显示光源颜色(如白光照射下物体变为纯白色,失去自身颜色)。

优点如下

  • 物理正确:符合能量守恒定律。
  • 计算高效:仅需一次点积运算。
  • 广泛兼容:所有现代图形API(OpenGL、Vulkan等)均支持。

缺点如下

  • 背面全黑:不符合实际场景(现实中存在间接光)。
  • 无高光:无法表现光滑材质的镜面反射(需结合其他模型)。

使用场景

  • 真实感渲染:适用于粗糙表面(如石头、布料)。
  • 实时渲染基础:常与Phong高光模型结合(如Blinn-Phong)。
  • 预计算光照:用于光照贴图(Lightmap)生成。

Half lambertian reflectance

半兰伯特光照模型是由Valve公司在《半条命2》中提出的,在数学变换中将兰伯特模型的余弦值从 [1,1][−1,1] 映射到 [0,1][0,1],旨在避免暗部完全黑暗的问题,使物体在低光照区域仍能保留一定的可见细节,从而产生更柔和的漫反射效果。

只考虑光源的情况下,公式如下所示。

Idiffuse=(0.5+0.5(nl))IlightI_{diffuse}= (0.5 + 0.5 \cdot (n \cdot l)) \cdot I_{light}
  • nn : 表面法向量(单位向量)
  • ll : 光源方向(单位向量)
  • IlightI_{light} : 光源强度

考虑到光照的控制,在计算光照强度的时候,开发人员往往会引入一个 γ\gamma 来控制光照的强度。

Idiffuse=(0.5+0.5(nl))γIlightI_{diffuse}= (0.5 + 0.5 \cdot (n \cdot l))^\gamma \cdot I_{light}
  • γ\gamma : 可选幂系数,用于调整明暗过渡的平滑度(默认为 1)
需求推荐 γ\gamma说明
性能优先(如手游)1避免 pow 运算,牺牲对比度
写实渲染(PBR管线)2.2匹配人眼感知,增强阴影深度
卡通/风格化渲染1~2灵活调整明暗风格
特殊效果(如梦境)less 1柔化阴影,营造朦胧感

引入材质的颜色,则公式成为

Idiffuse=kd(0.5+0.5(nl))γIlightI_{diffuse}= k_d \cdot (0.5 + 0.5 \cdot (n \cdot l))^\gamma \cdot I_{light}

优点如下

  • 避免暗部完全黑死,卡通渲染中很好用。
  • 计算高效,仅需一次点积和线性运算,比复杂的物理光照模型(如PBR)更轻量,适合移动端或性能敏感场景。
  • 艺术控制灵活,通过控制 γ\gamma 能够实现各种风格的效果。
  • 兼容性好,无需复杂的光照预处理,直接集成到标准着色器中,兼容前向渲染和延迟渲染管线。

缺点如下

  • 物理不准确,

  • 非能量守恒:背面人为补光不符合真实物理规律(现实中漫反射光不会来自背面)。不适用于写实渲染:如PBR管线需严格遵循能量守恒,半兰伯特可能破坏材质真实性。

  • 对比度依赖手动调整,缺乏自适应能力(无法像全局光照(GI)那样动态响应环境光)。

  • 暗部可能“发灰”,默认参数下,暗部亮度固定为 0.5Ilight0.5 \cdot I_light,若光源较强可能导致暗部显得不自然。

  • 不适用于高光材质,无法模拟镜面高光(需结合Phong/Blinn-Phong等模型)。

应用场景

  • 卡通渲染(Cel Shading):配合阈值化处理,实现分阶明暗效果。
  • 低光照环境:避免物体背面完全丢失细节(如地下城游戏)。
  • 风格化角色:增强艺术表现力,如《半条命2》中的角色渲染。

Phong reflection model

Phong 高光模型是计算机图形学中经典的镜面反射模型,由 Bui Tuong Phong 于1975年提出。它用于模拟光滑表面(如金属、塑料)的高光反射效果,通常与兰伯特漫反射模型结合使用。

Phong 光照模型将光分解为环境光,漫反射,镜面反射三个分量相加。

img

在 Phong 光照模型的视角里,镜面反射的光强取决于视线方向与光线反射方向的夹角,通过余弦函数的幂次控制高光锐利度。

Ispecular=ks(rv)αIlightI_{specular} = k_s \cdot (\mathbf{r} \cdot \mathbf{v})^\alpha \cdot I_{light}
  • ksk_s : 镜面反射系数(材质的高光颜色,通常为白色或浅灰色)
  • r\mathbf{r} : 光线反射方向,入射光 ll 关于法线 nn 的对称向量,计算公式为 r=2(nl)nlr = 2(\mathbf{n} \cdot \mathbf{l})n - l
  • v\mathbf{v} : 视线方向(从表面点到摄像机的向量)
  • α\alpha : 高光指数(控制高光集中度,值越大高光越锐利)

结合漫反射后的完整公式为

Itotal=Iambient+Idiffuse+Ispecular=kaIlight+kdmax(0,nl)Ilight+ks(rv)αIlight\begin{align} I_{total} &= I_{ambient} + I_{diffuse} + I_{specular} \\ &= k_{a} I_{light} + k_d max(0, \mathbf{n} \cdot \mathbf{l}) I_{light} + k_s (\mathbf{r} \cdot \mathbf{v})^\alpha I_{light} \end{align}
  • ItotalI_{\text{total}} : 总光照强度(Total illumination)
  • kak_a : 环境光反射系数(Ambient reflection coefficient),是基于材质属性的经验参数
  • kdk_d : 漫反射系数(Diffuse reflection coefficient)
  • ksk_s : 镜面反射系数(Specular reflection coefficient)
  • n\mathbf{n} : 表面法线向量(Surface normal vector)
  • l\mathbf{l} : 光源方向向量(Light direction vector)
  • r\mathbf{r} : 反射向量(Reflection vector)
  • v\mathbf{v} : 观察方向向量(View direction vector)
  • α\alpha : 镜面反射指数/高光锐度(Specular exponent/Shininess)
  • IlightI_{\text{light}} : 光源强度(Light intensity)

Blinn-Phong reflection model

Blinn-Phong 是 Phong 光照模型的改进版本,由 Jim Blinn 在 1977 年提出。它优化了 Phong 的高光计算方式,使其在计算效率和视觉效果上更优,至今仍广泛应用于实时渲染(如游戏、移动端图形)。

Phong 的高光计算依赖 反射向量 r\mathbf{r},而 Blinn-Phong 改用 半角向量 h\mathbf{h},减少了计算量并改善了高光表现。

h=normalize(l+v)=l+vl+v\mathbf{h} = normalize(\mathbf{l}+\mathbf{v}) = \frac{\mathbf{l} + \mathbf{v}}{\|\mathbf{l} + \mathbf{v}\|}
  • l\mathbf{l} :归一化的光源方向向量(从表面点指向光源)
  • v\mathbf{v} :归一化的视线方向向量(从表面点指向摄像机)
  • l+v\| \mathbf{l} + \mathbf{v} \|:向量长度(归一化保证 h\mathbf{h} 是单位向量)

除此之外,Blinn-Phong 的光照公式和 Phong 完全相同,也是将光分解为环境光,漫反射,镜面反射三个分量相加。

Blinn-Phong 的高光计算公示如下。

Ispec=ks(nh)αIlightI_{spec} = k_s \cdot (\mathbf{n} \cdot \mathbf{h})^\alpha \cdot I_{light}
  • n\mathbf{n}:表面法线
  • h\mathbf{h}:半角向量,光源与视线的夹角

Blinn-Phong 完整公式如下。

Itotal=Iambient+Idiffuse+Ispecular=kaIlight+kdmax(0,nl)Ilight+ks(nh)αIlight\begin{align} I_{total} &= I_{ambient} + I_{diffuse} + I_{specular} \\ &= k_{a} I_{light} + k_d max(0, \mathbf{n} \cdot \mathbf{l}) I_{light} + k_s \cdot (\mathbf{n} \cdot \mathbf{h})^\alpha \cdot I_{light} \end{align}

Phong 与 Blinn-Phong 的比较

模型提出者年份核心贡献
PhongBui Tuong Phong1975首次量化镜面高光强度
Blinn-PhongJim Blinn1977引入半角向量优化计算

Phong光照模型的光学原理

基于表面微平面理论的近似模型,假设:

  • 漫反射服从 Lambert 余弦定律
  • 镜面反射强度与视角-反射方向夹角相关

Blinn-Phong 的改进

引入半角向量理论对高亮计算进行了优化。

什么是半角向量

半角向量(Halfway Vector)理论是计算机图形学中用于简化镜面反射计算的核心数学工具,由Jim Blinn在1977年提出,作为对Phong模型的改进。

在微表面模型(Microfacet Theory)框架下,表面由无数微观镜面组成,只有当微法线与hh对齐时,该微平面才对镜面反射有贡献,而 nh\mathbf{n} \cdot \mathbf{h} 量化了有效反射面的比例。

Phong 依赖的向量 r\mathbf{r} 是理想镜面反射方向,而 Blinn-Phong 依赖的向量 h\mathbf{h} 是统计意义的有效反射面法向分布。

常见材质的预设值

材质类型kak_akdk_dksk_sα\alpha
抛光金属0.01-0.030.1-0.3 (灰度)0.7-0.9100-300
塑料0.05-0.1RGB(0.6,0.6,0.6)0.3-0.520-50
皮肤0.15-0.2RGB(0.8,0.4,0.3)0.04-0.0810-20