Shader 101-03 - Lighting
基础光照模型
Lambertian reflectance
兰伯特光照模型(Lambertian Reflectance Model)是计算机图形学中最基础的漫反射光照模型,由18世纪科学家约翰·海因里希·兰伯特(Johann Heinrich Lambert)提出。它描述了理想漫反射表面(如粗糙的石膏、纸张)的光照行为,其核心特点是:光线在所有方向均匀散射,观察角度不影响亮度。
以下是一个简化的公式,只考虑光照的反射。 $$ I_{diffuse} = max(0, n \cdot l) \cdot I_{light} $$
- $n$ : 表面法向量(单位向量)
- $l$ : 光源方向(单位向量)
- $I_{light}$ : 光源强度
完整的公式需要加上物理材质本身的颜色,公式如下所示。 $$ I_{diffuse} = k_d \cdot max(0, n \cdot l) \cdot I_{light} $$
- $k_d$ : 物体漫反射颜色(材质颜色)
$k_d$ 表示物体表面对不同波长光线的反射率(例如,红色物体反射更多红光),若省略 $k_d$,物体将完全显示光源颜色(如白光照射下物体变为纯白色,失去自身颜色)。
优点如下
- 物理正确:符合能量守恒定律。
- 计算高效:仅需一次点积运算。
- 广泛兼容:所有现代图形API(OpenGL、Vulkan等)均支持。
缺点如下
- 背面全黑:不符合实际场景(现实中存在间接光)。
- 无高光:无法表现光滑材质的镜面反射(需结合其他模型)。
使用场景
- 真实感渲染:适用于粗糙表面(如石头、布料)。
- 实时渲染基础:常与Phong高光模型结合(如Blinn-Phong)。
- 预计算光照:用于光照贴图(Lightmap)生成。
Half lambertian reflectance
半兰伯特光照模型是由Valve公司在《半条命2》中提出的,在数学变换中将兰伯特模型的余弦值从 $[−1,1]$ 映射到 $[0,1]$,旨在避免暗部完全黑暗的问题,使物体在低光照区域仍能保留一定的可见细节,从而产生更柔和的漫反射效果。
只考虑光源的情况下,公式如下所示。 $$ I_{diffuse}= (0.5 + 0.5 \cdot (n \cdot l)) \cdot I_{light} $$
- $n$ : 表面法向量(单位向量)
- $l$ : 光源方向(单位向量)
- $I_{light}$ : 光源强度
考虑到光照的控制,在计算光照强度的时候,开发人员往往会引入一个 $\gamma$ 来控制光照的强度。 $$ I_{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 | 柔化阴影,营造朦胧感 |
引入材质的颜色,则公式成为 $$ I_{diffuse}= k_d \cdot (0.5 + 0.5 \cdot (n \cdot l))^\gamma \cdot I_{light} $$ 优点如下
- 避免暗部完全黑死,卡通渲染中很好用。
- 计算高效,仅需一次点积和线性运算,比复杂的物理光照模型(如PBR)更轻量,适合移动端或性能敏感场景。
- 艺术控制灵活,通过控制 $\gamma$ 能够实现各种风格的效果。
- 兼容性好,无需复杂的光照预处理,直接集成到标准着色器中,兼容前向渲染和延迟渲染管线。
缺点如下
物理不准确,
非能量守恒:背面人为补光不符合真实物理规律(现实中漫反射光不会来自背面)。不适用于写实渲染:如PBR管线需严格遵循能量守恒,半兰伯特可能破坏材质真实性。
对比度依赖手动调整,缺乏自适应能力(无法像全局光照(GI)那样动态响应环境光)。
暗部可能“发灰”,默认参数下,暗部亮度固定为 $0.5 \cdot I_light$,若光源较强可能导致暗部显得不自然。
不适用于高光材质,无法模拟镜面高光(需结合Phong/Blinn-Phong等模型)。
应用场景
- 卡通渲染(Cel Shading):配合阈值化处理,实现分阶明暗效果。
- 低光照环境:避免物体背面完全丢失细节(如地下城游戏)。
- 风格化角色:增强艺术表现力,如《半条命2》中的角色渲染。
Phong reflection model
Phong 高光模型是计算机图形学中经典的镜面反射模型,由 Bui Tuong Phong 于1975年提出。它用于模拟光滑表面(如金属、塑料)的高光反射效果,通常与兰伯特漫反射模型结合使用。
Phong 光照模型将光分解为环境光,漫反射,镜面反射三个分量相加。
在 Phong 光照模型的视角里,镜面反射的光强取决于视线方向与光线反射方向的夹角,通过余弦函数的幂次控制高光锐利度。 $$ I_{specular} = k_s \cdot (\mathbf{r} \cdot \mathbf{v})^\alpha \cdot I_{light} $$
- $k_s$ : 镜面反射系数(材质的高光颜色,通常为白色或浅灰色)
- $\mathbf{r}$ : 光线反射方向,入射光 $l$ 关于法线 $n$ 的对称向量,计算公式为 $r = 2(\mathbf{n} \cdot \mathbf{l})n - l$
- $\mathbf{v}$ : 视线方向(从表面点到摄像机的向量)
- $\alpha$ : 高光指数(控制高光集中度,值越大高光越锐利)
结合漫反射后的完整公式为
$$ \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} $$
- $I_{\text{total}}$ : 总光照强度(Total illumination)
- $k_a$ : 环境光反射系数(Ambient reflection coefficient),是基于材质属性的经验参数
- $k_d$ : 漫反射系数(Diffuse reflection coefficient)
- $k_s$ : 镜面反射系数(Specular reflection coefficient)
- $\mathbf{n}$ : 表面法线向量(Surface normal vector)
- $\mathbf{l}$ : 光源方向向量(Light direction vector)
- $\mathbf{r}$ : 反射向量(Reflection vector)
- $\mathbf{v}$ : 观察方向向量(View direction vector)
- $\alpha$ : 镜面反射指数/高光锐度(Specular exponent/Shininess)
- $I_{\text{light}}$ : 光源强度(Light intensity)
Blinn-Phong reflection model
Blinn-Phong 是 Phong 光照模型的改进版本,由 Jim Blinn 在 1977 年提出。它优化了 Phong 的高光计算方式,使其在计算效率和视觉效果上更优,至今仍广泛应用于实时渲染(如游戏、移动端图形)。
Phong 的高光计算依赖 反射向量 $\mathbf{r}$,而 Blinn-Phong 改用 半角向量 $\mathbf{h}$,减少了计算量并改善了高光表现。 $$ \mathbf{h} = normalize(\mathbf{l}+\mathbf{v}) = \frac{\mathbf{l} + \mathbf{v}}{|\mathbf{l} + \mathbf{v}|} $$
- $\mathbf{l}$ :归一化的光源方向向量(从表面点指向光源)
- $\mathbf{v}$ :归一化的视线方向向量(从表面点指向摄像机)
- $| \mathbf{l} + \mathbf{v} |$:向量长度(归一化保证 $\mathbf{h}$ 是单位向量)
除此之外,Blinn-Phong 的光照公式和 Phong 完全相同,也是将光分解为环境光,漫反射,镜面反射三个分量相加。
Blinn-Phong 的高光计算公示如下。 $$ I_{spec} = k_s \cdot (\mathbf{n} \cdot \mathbf{h})^\alpha \cdot I_{light} $$
- $\mathbf{n}$:表面法线
- $\mathbf{h}$:半角向量,光源与视线的夹角
Blinn-Phong 完整公式如下。 $$ \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 的比较
模型 | 提出者 | 年份 | 核心贡献 |
---|---|---|---|
Phong | Bui Tuong Phong | 1975 | 首次量化镜面高光强度 |
Blinn-Phong | Jim Blinn | 1977 | 引入半角向量优化计算 |
Phong光照模型的光学原理
基于表面微平面理论的近似模型,假设:
- 漫反射服从 Lambert 余弦定律
- 镜面反射强度与视角-反射方向夹角相关
Blinn-Phong 的改进
引入半角向量理论对高亮计算进行了优化。
什么是半角向量
半角向量(Halfway Vector)理论是计算机图形学中用于简化镜面反射计算的核心数学工具,由Jim Blinn在1977年提出,作为对Phong模型的改进。
在微表面模型(Microfacet Theory)框架下,表面由无数微观镜面组成,只有当微法线与hh对齐时,该微平面才对镜面反射有贡献,而 $\mathbf{n} \cdot \mathbf{h}$ 量化了有效反射面的比例。
Phong 依赖的向量 $\mathbf{r}$ 是理想镜面反射方向,而 Blinn-Phong 依赖的向量 $\mathbf{h}$ 是统计意义的有效反射面法向分布。
常见材质的预设值
材质类型 | $k_a$ | $k_d$ | $k_s$ | $\alpha$ |
---|---|---|---|---|
抛光金属 | 0.01-0.03 | 0.1-0.3 (灰度) | 0.7-0.9 | 100-300 |
塑料 | 0.05-0.1 | RGB(0.6,0.6,0.6) | 0.3-0.5 | 20-50 |
皮肤 | 0.15-0.2 | RGB(0.8,0.4,0.3) | 0.04-0.08 | 10-20 |