渲染方程
Rendering Equation
渲染方程 (Kajiya, 1986) 把"某点接收到的光就是其他点发出或反射的光"写成递归积分,概括了光从光源出发经任意次反弹到达眼睛的所有路径。反射方程是它的受限特例。离线用辐射度 (Radiosity) 或蒙特卡洛路径追踪求解;实时渲染则靠简化和预计算逼近它(RTR4 第 11 章)。
从反射方程到渲染方程
前面各章用的反射方程把入射辐射亮度 当作已知:
渲染方程加入自发光项 ,并把入射亮度替换为另一点的出射亮度:
其中 是光线投射函数,返回从 沿 射出的光线击中的第一个表面点。z-buffer 实际上就在为从眼睛出发的光线计算它。唯一的新东西是递归项 :要算它又需要在 处再积分,无穷无尽。
关键性质:渲染方程对发光量是线性的——光源加倍,结果加倍;各光源对材质的作用互不影响。这条性质是预计算辐射传输的基础。
局部光照与全局光照
GPU 最擅长的是局部光照:图元独立处理、光栅化后丢弃,算点 b 时拿不到点 a 的光照结果。透明、反射、阴影都是需要其他物体信息的全局光照算法,能大大增加真实感和空间关系线索,但往往需要预计算或多遍渲染。
Heckbert 光路表示法
把光子从光源 (L) 到眼睛 (E) 路径上的每次交互标为漫反射 (D) 或镜面 (S),可再加"光泽"(glossy) 等类型,用正则表达式概括算法模拟了哪些路径:
| 运算符 | 含义 | 例子 |
|---|---|---|
* | 零次或多次 | S* 零或多次镜面反弹 |
+ | 一次或多次 | D+ 至少一次漫反射 |
? | 零或一次 | S? |
| | 二选一 | D|SS |
() | 分组 | (D|S)* |
| 系统 | 光路 |
|---|---|
| 基本 z-buffer | L(D|S)E |
| 光源有几何体(可直接看到) | L(D|S)?E |
| 加入环境贴图 | L((S|D)?S|D)?E,即 L(D|S)?S?E;生成环境贴图编码 L(S|D),访问它是 SE |
| 辐射度 | LD*E |
| 渲染方程本身 | L(D|S)*E |
| 漫反射全局光照 / 镜面全局光照 | L(D|S)*DE / L(D|S)*SE |
书中建议从眼睛往回推更容易写出表达式。实时全局光照最常用的两种策略是简化(比如假设到达眼睛前的反弹都是漫反射)和预计算(离线把光照存进纹理等)。
为什么实时渲染也要了解离线算法
- 静态或部分静态场景可以把它们当预处理运行(烘焙),游戏中很常见;
- 它们有严格的理论基础,近似都经过分析。设计实时方案时也应知道捷径的后果和正确做法是什么。
辐射度 (Radiosity)
- 第一个模拟漫反射表面间光线反弹的图形学技术,可计算面光源的相互反射和软阴影。假设所有间接光来自漫反射表面(抛光大理石、大镜子会失效,建筑场景通常可接受),可跟踪实际上无限次漫反射反弹。
- 表面分成若干面片,每片一个平均值;面片要小到能捕捉阴影边缘等细节,但不必与三角形一一对应或等大。
为面片 的辐射出射度(只有光源非零), 为次表面反照率, 为形状因子:
为可见性(0/1), 为两面片法线与连线的夹角, 为距离。形状因子是纯几何量:面片 均匀漫射出的能量落到 上的比例,所有比例之和为 1。所有方程组成线性系统求解;面片增多后求解代价极高,所以经典辐射度很少再用,但"预计算形状因子、运行时传播光"的思路仍是现代实时 GI(如 Enlighten)的基础。
光线追踪与路径追踪
- 经典光线追踪:从相机穿过像素发射光线找最近交点,向各光源发射阴影光线(不透明物体遮挡、透明物体衰减),光滑表面沿反射方向、透明体沿折射方向递归。只能做锐利反射/折射和硬阴影。
- Kajiya 意识到发射光线可以用来计算渲染方程积分:蒙特卡洛方法在定义域随机点上评估被积函数来估计积分,只需要点评估,样本越多越准。每条光线就是对被积函数的一次点采样,交点处的积分不必求出最终值,再点采样即可;光线在场景中弹跳形成一条路径,这就是路径追踪。
- 路径追踪能处理光泽和漫反射材质、软阴影、透明与焦散;扩展到体积采样后还能处理雾和次表面散射。
- 缺点:只得到估计值,路径太少时方差高,表现为图像噪点;电影级画面可能需要数十亿条路径(书中示例:每像素两千多条、每条最多 64 段,渲染两小时仍有少量噪点)。重要性采样在光多的方向多发光线,可大幅降低方差。
- 离线 GI 中光线追踪远比辐射度流行:能在同一框架里处理一般光传输(包括体积散射),也更易扩展和并行。
统一方法:实时路径追踪的前景
- 各种实时 GI 技术组合起来能出好图,但每部分都有不同折中,许多情况下幻觉会破灭,缺少路径追踪的优雅。
- 实时路径追踪已用于建筑漫游和电影预览(可接受较低帧率、相机静止时渐进细化、多 GPU);游戏需要每帧在预算内给出最终质量,GPU 还要做粒子模拟等工作,书中认为纯路径追踪当时尚不实用。圈内俗语:"光线追踪是未来的技术,而且永远都是!"——GPU 为光栅化而设计,缺少光线追踪的固定功能支持。
- 更现实的是混合:光栅化主可见性,用路径追踪做反射、面光源阴影等光栅化难处理的效果。"帧率不可妥协",为几毫秒牺牲一些优雅是正确选择。
- GPU 上 BVH 遍历要减少 warp 内分支分歧、复用提前结束的线程;每像素一条路径的噪声图可用降噪算法(如时空方差引导滤波 SVGF)得到接近 2048 spp 参考的结果。PowerVR Wizard GPU (2014) 已含构建和遍历加速结构的硬件单元。
GEA 的视角:光照问题、渲染方程的推导与辐射度方法(卷 II 12.1、12.2.1.1、12.3、12.6.1)
光照问题、直接与间接光照
- GEA 把渲染问题拆成可见性问题和光照问题:先找到每个虚拟传感器能直接看到的表面点 (发射光线或深度缓冲光栅化),再求这些点送到传感器的光的颜色和强度(卷 II 12.1,见 图形栈与渲染引擎架构)。
- 直接光照指光子从光源发出、恰好在一个表面反射一次后进入相机;间接光照指进入相机前反射多于一次。间接光要递归计算、还要考虑来自所有方向的入射光,代价高得多。实践中可以忽略间接光或粗略近似它来得到"可信但不照片级"的图像,追求真实感的历史,主要就是不断改进间接光近似的历史(卷 II 12.1.3)。
- 只考虑直接光源叫局部光照模型,同时考虑间接光的叫全局光照模型;全局光照模型通常还包括次表面散射和参与介质中的散射与吸收。照片级真实感只能靠全局光照(卷 II 12.1.4)。这与本页上文 RTR4 从"GPU 擅长局部光照"角度的说法一致。
光路表示法:GEA 的写法
GEA 用的符号是 L(光源)、D(漫反射)、G(半漫反射或光泽反射)、S(镜面)、E(眼睛或相机),并只用 * 和 +。所有光路为 L(D|G|S)*E;直接光照为 L(D|G|S)E 或 LE;间接光照为 L(D|G|S)+E;辐射度方法只能处理 LD*E(卷 II 12.2.1.1)。
原书问题(12.2.1.1):按正则表达式语义,
L(D|G|S)+E也匹配只反弹一次的L(D|G|S)E,与同一句里的"直接光照"重叠,并非"其余所有光路"。按 GEA 自己在 12.1.3 的定义(间接光照=反弹多于一次),间接光照应写成L(D|G|S)(D|G|S)+E(即L(D|G|S){2,}E)。+表示"一次或多次"的含义见 Heckbert, "Adaptive Radiosity Textures for Bidirectional Ray Tracing", SIGGRAPH 1990 引入的光路正则表示法,以及任一正则表达式规范(如 POSIX ERE)。与上表 RTR4 的 Heckbert 表示法相比,GEA 把光泽反射提升为基本符号 G,RTR4 只说可以"再加光泽类型"。
推导:从"魔法因子"到 BRDF
GEA 的推导路线是:出射亮度 = 自发光 + 反射();反射部分必须对半球上所有入射方向积分,先写成 。从单位分析可知 的单位是 sr⁻¹。把 BRDF 定义为反射亮度对入射辐照度的导数 ,再代入 ,就得到 和完整的渲染方程(卷 II 12.3.1–12.3.2):
渲染方程由 Immel 等与 Kajiya 在 1986 年独立提出,是线性积分方程(卷 II 12.3)。本页开头只提 Kajiya,GEA 补充了 Immel 等的同期工作。
各种写法其实是同一个方程
GEA 专门对比了文献中的写法(卷 II 12.3.3):
- 向量形式:方向写成单位向量,出射方向为视线向量 、入射方向为光照向量 ,两者都约定背离表面(对 来说与光子行进方向相反);余弦写成 ,即 HLSL 的
saturate。(原书问题:GEA 说 HLSL 提供sat()或saturate();HLSL 内建函数表中只有saturate,没有sat(MS Learn "Intrinsic Functions (HLSL)")。另外saturate钳到 ,对单位向量点积而言上限无影响,等价于 。) 不一定真指向光源, 也不一定指向观察者。 - RTR4 的写法 :左边是相机成像面点 收到的亮度,等价于可见表面点 的出射亮度,与本页上文一致。
- Kajiya 原文用"传输强度"(对源点面积和目标点面积的二阶导数),配几何项 、发射项 和类似 BRDF 的 ,作用与辐射亮度相同。Kajiya 的原式是 。 注意几何项 (不可见为 0,可见为 )乘的是发射与散射两项之和(Kajiya, "The Rendering Equation", SIGGRAPH 1986 式 (1);Wikipedia "Path tracing")。GEA 电子版文本层中此式没有方括号,看起来像 ;由于积分号、、 等数学字体字符在文本层中同样缺失,无法确认是排版丢失还是原书漏写,阅读时以 Kajiya 原式为准。
- 面积形式(Dutré 等):对场景所有表面积分,,再乘可见性 。单位分析:,所以 的量纲仍是 sr,与 BRDF 的 sr⁻¹ 相消。面积形式是辐射度方法的基础,也适合光线追踪,因为 正是光线投射函数(本页上文的 )。
光度学 RGB 形式与颜色向量
- 把方程拆成 R、G、B 三个独立方程,用光度学量(流明为基础的单位)计算,是"物理上可信但不严格正确"的近似;严格做法要把波长 作为额外自变量(卷 II 12.3.4)。
- 颜色像向量一样可以相加、数乘,但:模长不是亮度,sRGB 下灰度亮度 (系数只适用于线性 sRGB 分量,即解码 gamma 之后的值,见 显示编码与 sRGB);GEA 说分量不能为负(物理上可信的颜色必在颜色空间第一卦限)——这只对谱色都在 sRGB 色域内的情况成立:sRGB 原色三角形之外的真实颜色(例如高饱和的青绿色谱色)换算成线性 sRGB 时必然有负分量(IEC 61966-2-1 色域;Wikipedia "sRGB"/"Gamut"),这也是宽色域渲染改用 ACEScg 等工作空间的原因;可以大于 1(HDR),最终写入帧缓冲前要色调映射或钳制到 ;颜色之间不做点积叉积,相乘是逐分量的 Hadamard 积。严格地说颜色相乘应乘光谱功率分布再转回 sRGB,但逐分量相乘的精度损失可以忽略(卷 II 12.3.4.1)。
- 因为积分没有闭式解、且递归可能成环,GEA 在下一节做两条简化得到着色方程,见 着色方程与经典光照模型。
辐射度方法:GEA 的补充
- 辐射度方法源自辐射传热的有限元方法,与视角无关,计算一次后相机移动时可以重复使用,但几何一变就要重算,不适合动态场景;它假设表面都是朗伯面,只能处理
LD*E,做不了镜面反射和硬阴影。PRT 和光照贴图都是受它启发的混合用法(卷 II 12.6.1,见 预计算辐射传输、预计算光照与光照贴图)。 - 只有朗伯面时,面积形式可以写成辐射度形式 ,离散成面片后 (卷 II 12.6.1.1)。
- 形状因子可以用半立方体 (hemicube) 计算:把单位半球换成以面元为中心的半个立方体,划分成方形"像素",把远处面片投影上去,统计各自可见的比例。
原书问题(12.6.1.1):GEA 把 称作形状因子 ,再把积分直接改写成 。但 的量纲是 m⁻²(乘 才无量纲),离散求和时必须乘面片面积 (或在面片上积分)才能代替 ;书中的离散式漏了这一项。标准写法里形状因子是无量纲的面积平均量 ,满足互易关系 ,离散方程为 (Cohen & Wallace,《Radiosity and Realistic Image Synthesis》第 2、4 章;Wikipedia "Radiosity (computer graphics)" 数学推导一节)。按 GEA 的 写法,应为 。
- 线性系统通常迭代求解:收集法 (gathering) 每次迭代从其他面片收集辐射度来更新一个面片,属于 Gauss-Seidel 松弛;发射法 (shooting) 把一个面片的辐射度发射给所有其他面片,属于 Southwell 松弛,适合渐进细化,每次迭代后都能输出一张图,质量随纳入的反弹次数逐步提高。
| 对照 | RTR4(本页上文) | GEA |
|---|---|---|
| 反射系数 | (次表面反照率) | (漫反射 BRDF) |
| 形状因子 | ,含 与 ,表示 发出的能量落到 上的比例 | 把 称为形状因子并记作 ,离散式里写 ,未显式出现 |
两者的 因子放的位置不同:GEA 的 已含 ,RTR4 把 放进形状因子,下标顺序也不同;读公式时要按各自的定义对应,不能直接混用。另外 GEA 正文把 称为"漫反射反射率",按它自己 12.4.3.2 的定义, 是 BRDF,反射率是 。
PBRT 的视角:光传输方程的三种形式(PBRT 4e 13.1)
PBRT 把渲染方程称为光传输方程 (Light Transport Equation, LTE),本节暂不考虑参与介质(第 14 章再加)。
由能量平衡推导(13.1.1)
宏观上 ;在表面上就是"出射 = 自发光 + 散射",散射项即散射方程(见 双向反射分布函数)。真空中辐亮度沿光线不变,定义光线投射函数 为从 沿 打到的第一个表面点(场景不封闭时返回特殊值 ,规定 ),则 ,于是
方程里只剩一个未知量:表面的出射辐亮度。
解析解与诺伊曼级数(13.1.2)
一般情况只能数值求解,但简单场景的解析解可用来调试积分器。例:球内表面处处是常数 BRDF 的朗伯面,且发射常数辐亮度 。由对称性各点各方向的 相同,LTE 化为 ;令 ,反复代入得
这是诺伊曼级数 (Neumann Series), 保证收敛;第 项就是散射 次的光。本页用一个 60 次反弹的随机游走模拟(、、20 万条路径)得到 2.501,理论值 2.5。只代入一次( 换成 )就是只算直接光照。
面积形式 / 三点形式(13.1.3)
把 的几何关系显式写进被积函数:记 为 射向 的辐亮度, 为 三点形式 BSDF,把立体角换成面积(雅可比 ,见 辐射度量学与光度学 的 PBRT 小节),与原有的 和二值可见性 合成几何耦合项
两种形式等价,但对应两种蒙特卡洛做法:式 13.1 采样方向再投射光线;式 13.3 在表面上按面积采样点,再追踪光线判断 。
路径积分形式(13.1.4)
把式 13.3 反复代入自身,得到按路径长度展开的和:
路径 有 个顶点, 在胶片或镜头前片上, 在光源上;路径通量 (throughput) (式 13.6),即光源辐亮度经各次散射后到达相机的比例。估计时只需按某个密度采样路径并计算 ;路径从相机、从光源、从两端还是从中间生成,只影响 怎么算。这种"测量值 = 路径空间上的显式积分"的写法比式 13.1 的递归定义更自由,是双向方法的基础。路径长度的记法与 Heckbert 表示法(上文)对应: 是直接看到光源(LE), 是直接光照(LDE 或 LSE)。
被积函数中的 δ 分布(13.1.5)
点光源、方向光以及完美镜面 BSDF 在被积函数里引入 δ 分布。随机方向永远打不到点光源,必须显式选指向光源的方向;但它也把对应的积分降成直接求值:例如单个点光源时 ,分子分母的 δ 抵消,无需蒙特卡洛。BSDF 中的每个 δ 分量也消掉一重面积积分。
拆分被积函数(13.1.6)
不同算法各擅长 LTE 的一部分(Whitted 光线追踪只处理 δ 镜面 BSDF,忽略漫反射与光泽面的多次散射)。为了"不漏也不重复",可以把 LTE 拆开:
- 按路径长度: 直接取自发光, 用精确的直接光照, 用快而粗的方法;后者必须忽略前两项。
- 按光源:(小光源/大光源)分别估计,每个光源只能归入一类。
- 按 BSDF 分量:;由于路径上有 个 BSDF 因子,像 这样的混合项都要计入。pbrt 的
BxDFFlags分类(9.1.2)正是为此。 游戏中的对应:烘焙光照贴图存间接光、运行时算直接光,就是按路径长度拆分;拆分时最常见的 bug 正是重复计算或漏算某一类路径(如自发光面既进了光照贴图又被当作动态光源)。
PBRT 的视角:传输方程是更一般的形式(PBRT 4e 14.1)
有参与介质时,光传输方程推广为传输方程(体积光传输方程):沿光线的亮度 = 表面出射亮度 × 透射率 + 沿途各点源函数(介质发射 + 内散射)× 透射率的积分(式 14.2)。真空中透射率恒为 1、源函数为 0,就退化为本页的表面形式。路径积分形式也随之推广:顶点可以在表面、介质内的真实散射点或零散射点,几何项中介质端的余弦取 1。详见 参与介质与体积散射 的「PBRT 的视角:体积光传输与体积路径追踪」。
出处
- realtime_rendering_4ed.pdf 第 11 章 Global Illumination
- Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
- Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 12 章 12.1、12.2.1.1、12.3、12.6.1 节
- PBRT 4e source excerpt: chapter 13 (Light Transport I Surface Reflection)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 13 章 13.1 节,pbr-book.org/4ed/Light_Transport_I_Surface_Reflection
- PBRT 4e source excerpt: chapter 14 (Light Transport II Volume Rendering)
- Pharr, Jakob, Humphreys《Physically Based Rendering: From Theory to Implementation》第 4 版(MIT Press, 2023)第 14 章 14.1 节,pbr-book.org/4ed/Light_Transport_II_Volume_Rendering