全局光照与局部光照
需要预先学习:
1. 局部光照(Local Illumination)
光照模型(illumination model)描述表面颜色如何由光源与材质决定。着色与渲染管线 里的着色是局部的:每个着色点独立计算颜色,只考虑光源与表面本身的属性(法线、材质系数),完全不考虑场景中其他物体的存在。
Blinn-Phong 模型是典型的局部光照模型(local illumination model),它把表面颜色拆成环境光、漫反射、高光三项之和。局部光照的"局部"体现在两点:
- 逐点独立:每个点的着色只依赖该点的法线、位置与光源,与其他点互不相干;
- 无视遮挡:着色点与光源之间有什么东西、有没有东西挡着,一概不知。
这两点决定了局部光照的固有局限。
1.1 局部光照的局限
因为每个点只知道自己和光源,局部光照算不出一系列依赖"场景其他部分"的效果:
| 效果 | 为什么局部光照做不到 | 补救手段 |
|---|---|---|
| 阴影 | 不知道光源与点之间是否有物体遮挡 | ShadowMapping(ShadowMap与PCF、PCSS) |
| 镜面反射 | 不知道其他物体长什么样 | 环境贴图、额外渲染一遍场景 |
| 折射 | 不知道背后物体的图像 | 额外渲染、光线追踪 |
| 间接光照 | 不知道光线从其他表面反弹过来 | 常数环境光(粗糙近似) |
可见,阴影、反射、折射、间接光照这四类效果,局部光照要么做不了,要么只能靠"加一个常数环境光"糊弄过去。这四类恰好都是"光与场景其他部分的相互作用",统称为全局光照(global illumination)的效果。
2. 全局光照(Global Illumination)
全局光照(global illumination,GI)指光照计算中考虑光在场景中的传播过程:光从光源出发,经过物体表面的吸收、反射、折射,在物体之间多次反弹,最终到达观察者。与局部光照"每点只看自己和光源"不同,全局光照把整个场景当作一个相互作用的整体来算。
一个更具体的区分:直接光照(direct illumination)指从光源直接照到表面的光;间接光照(indirect illumination)指经过其他表面反弹之后才到达的光。局部光照只处理直接光照(外加一个常数近似间接光),全局光照同时处理两者——而且通常间接光部分才是计算的主要成本。
注:局部光照与全局光照不是两种互斥的渲染技术,而是两个层次的描述:局部光照是"逐点独立"的假设,全局光照是"考虑相互作用"的目标。任何渲染算法都可以评估它做到了哪一层——光线追踪天然是全局的,光栅化 + ShadowMapping + 常数环境光则停留在局部层。
2.1 全局光照产生哪些效果
全局光照的效果不止"阴影区域更亮",常见的包括:
| 效果 | 英文 | 现象 |
|---|---|---|
| 间接光照 | indirect illumination | 光线多次反弹后照亮背光面,阴影不再是纯黑 |
| 颜色溢出 | color bleeding | 红墙反射红光,把旁边的白墙染上淡红色 |
| 焦散 | caustics | 光线经水面折射、金属反射后汇聚成亮斑 |
| 环境光遮蔽 | ambient occlusion | 物体交界的缝隙处间接光被遮挡,形成柔和的暗角 |
其中颜色溢出与焦散是"能不能看出是全局光照"的标志性效果——局部光照无论怎么调参数都出不来,因为它们必须依赖"光从别的表面来"这一事实。
3. 全局光照的实现方法
全局光照的"正确解"是模拟光的传播本身,但精确模拟极慢。从离线到实时,各种方法在速度与精度之间取平衡。
3.1 光线追踪与路径追踪
光线追踪(光线追踪)从摄像机发射光线,逆向模拟光路。但 Whitted 风格只沿镜面反射/折射方向追踪,漫反射处直接采样光源,阴影依旧是硬阴影,间接光照依旧是近似。路径追踪(path tracing)更进一步:在漫反射表面也随机反弹光线,一条路径一路追到光源或逃逸,多次采样后按渲染方程做蒙特卡洛积分收敛——它是目前离线渲染的工业标准,效果上就是"真实"的代名词。
代价是收敛慢:一个像素往往要成百上千条路径才能去噪,因此路径追踪主要用于电影、建筑可视化等离线场景。近年 NVIDIA RTX 等硬件光追单元加降噪技术,把它推进到了实时领域。
3.2 辐射度(Radiosity)
辐射度(radiosity)是 1980 年代发展起来的方法,专门处理漫反射表面之间的能量传递:把场景表面划分成小面片,解一个关于面片间能量交换的线性方程组,得到每块表面发出的辐射度。
辐射度天然擅长颜色溢出——能量在漫反射表面间反复传递,与真实情况一致。但它的假设是场景只含漫反射(没有镜面高光),且结果与视点无关(view-independent),适合室内漫反射场景的离线预计算。
3.3 光子映射(Photon Mapping)
光子映射(photon mapping)分两步走:先从光源发射大量光子(携带能量的小包),让它们在场景中反弹并记录每个命中点(形成光子图);渲染时再查询光子图,估计表面每点的间接辐照度。
光子映射能处理焦散:光子在折射、反射后汇聚的区域光子密度高,亮度就高。两步结构让它能配合任意 BRDF,常用于焦散与复杂折射效果。
3.4 实时全局光照
实时光栅化管线(OpenGL 等)里,"真"全局光照算不动,工业界用一系列预计算 + 近似手段组合出实时 GI。常见套路:
| 技术 | 做法 | 覆盖的效果 |
|---|---|---|
| 环境贴图 / IBL | 把远处环境的光照烘焙成贴图(如天空盒),运行时按法线采样 | 来自环境的间接漫反射与镜面反射(PBR) |
| 光照贴图(lightmap) | 离线预计算场景的间接光,烘焙进 UV 纹理 | 静态场景的间接漫反射、颜色溢出 |
| 光照探针(light probe) | 在场景中稀疏放置探针记录光照,运行时插值 | 动态物体的间接光 |
| 球谐光照(SH) | 用球谐函数压缩低频光照,逐顶点 / 逐探针存储 | 大面积低频间接光 |
| 环境光遮蔽(AO) | 只计算"间接光被遮挡"的暗角,分 SSAO、HBAO 等 | 缝隙与交界的柔和阴影 |
| 反射探针(reflection probe) | 从探针位置渲染周围场景成立方体贴图 | 动态物体上的镜面反射 |
| VXGI / 体素全局光照 | 把场景体素化,从体素场查询间接光 | 动态场景的实时 GI |
这些方法各管一块,组合起来就是游戏引擎里的"全局光照":lightmap 管静态场景的漫反射间接光,探针管动态物体,环境贴图管天空,AO 补缝隙暗角——每一块都是对真实 GI 的局部近似。
注:把"实时 GI"理解成一个由多种近似技术拼成的工具箱,比期待某个单一算法"搞定一切"更接近实际。到底用哪几样,取决于场景是静态还是动态、室内还是室外、预算多少。
4. 局部与全局:如何选择
| 维度 | 局部光照 | 全局光照 |
|---|---|---|
| 计算范围 | 每点独立,只看光源 | 光在场景中传播、反弹 |
| 阴影 | 需要额外 ShadowMapping | 天然包含(硬 / 软) |
| 反射 / 折射 | 需要额外手段 | 天然包含 |
| 间接光照 | 常数环境光近似 | 显式计算多次反弹 |
| 典型实现 | Blinn-Phong、PBR 直接光 | 路径追踪、辐射度、光子映射 |
| 实时性 | 快,实时管线主力 | 慢,离线为主;实时靠近似组合 |
回到渲染管线的视角:着色与渲染管线 的光栅化管线配 Blinn-Phong 是纯局部光照,阴影靠 ShadowMapping 补救;光线追踪 把阴影、反射、折射、间接光一次性纳入流程,是走向全局光照的第一步,而路径追踪把它做到了物理正确。


