需要预先学习:


1. 局部光照(Local Illumination)

光照模型(illumination model)描述表面颜色如何由光源与材质决定。着色与渲染管线 里的着色是局部的:每个着色点独立计算颜色,只考虑光源与表面本身的属性(法线、材质系数),完全不考虑场景中其他物体的存在。

Blinn-Phong 模型是典型的局部光照模型(local illumination model),它把表面颜色拆成环境光、漫反射、高光三项之和。局部光照的"局部"体现在两点:

  1. 逐点独立:每个点的着色只依赖该点的法线、位置与光源,与其他点互不相干;
  2. 无视遮挡:着色点与光源之间有什么东西、有没有东西挡着,一概不知。

这两点决定了局部光照的固有局限。


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 补救;光线追踪 把阴影、反射、折射、间接光一次性纳入流程,是走向全局光照的第一步,而路径追踪把它做到了物理正确。