all lessons / computer_graphics / 12 · real-time GI lesson 12 / 15

Real-time global illumination — approximating transport in 16 milliseconds实时全局光照——在 16 毫秒内近似光传输

Lesson 11 built a Monte Carlo estimator for the rendering equation and stated the contracts under which its raw accumulation is unbiased. Driving that raw error low can cost hundreds to thousands of paths per pixel. A game has about 16 ms per frame, so it chooses a different error–latency contract: a few transport samples plus cached, approximate, and temporally reused information. This lesson studies three recurring tactics — precompute, approximate, and amortize — through shadow maps, ambient occlusion, baked light, probes, and screen-space reflections. 第 11 课为渲染方程构造了蒙特卡洛估计器,并说明原始累积在什么契约下无偏。要把原始误差压低,每像素可能需要数百到数千条路径。游戏每帧只有约 16 毫秒,因此选择另一套误差–延迟契约:少量光传输样本,加上缓存、近似和跨帧复用的信息。本课通过阴影贴图、环境光遮蔽、烘焙光照、探针与屏幕空间反射,研究三种反复出现的策略:预计算近似摊销

The plan本课计划

Five moves. (1) The budget wall: restate why a low-error raw Monte Carlo estimate is unaffordable per frame at typical budgets, and name three recurring responses — precompute (bake), approximate (screen-space or sparse sampling), and amortize (temporal reuse). They are a useful taxonomy, not an exhaustive theorem; modern renderers also combine importance sampling, spatial reuse, upscaling, specialized hardware, and learned reconstruction. (2) Shadows via shadow mapping: render depth from the light's view, then compare; meet acne and peter-panning and the bias that trades between them, then PCF and cascades. (3) Ambient occlusion: the "how open is the sky here" term, approximated in screen space by SSAO. (4) Precomputed indirect light: radiosity, lightmaps (static only), and irradiance probes with spherical harmonics (for dynamic objects). (5) Screen-space and the new era: SSR and its on-screen-only limit, then hardware ray tracing + ML denoising + DDGI closing the gap to dynamic GI (bridge to lesson 15). The widget dissects the single most instructive bug in the set: shadow-map bias.

五步走。(1) 预算之墙:重申为何在典型逐帧预算下无法负担低误差的原始蒙特卡洛估计,并点出三种反复出现的应对——预计算(烘焙)、近似(屏幕空间或稀疏采样)、摊销(时序复用)。它们是一套有用的分类,不是穷尽一切的定理;现代渲染器还会组合重要性采样、空间复用、上采样、专用硬件与学习式重建。(2) 用阴影贴图做阴影:从光源视角渲染深度,再比较;见识阴影痤疮彼得潘,以及在二者之间权衡的偏置,然后是 PCF 与级联。(3) 环境光遮蔽:那个“这里天空有多开阔”的项,由 SSAO 在屏幕空间近似。(4) 预计算间接光:辐射度、光照贴图(仅限静态)、以及带球谐的辐照度探针(用于动态物体)。(5) 屏幕空间与新纪元:SSR 及其“只有屏幕上才有”的局限,然后是硬件光线追踪 + ML 去噪 + DDGI 逼近动态 GI(通往第 15 课的桥)。小控件将解剖整套方法里最有教益的那个 bug:阴影贴图偏置。

1 · The budget wall — offline-quality convergence does not fit one frame预算之墙——离线质量的收敛塞不进一帧

Recall the constraint from lesson 01: a real-time frame must finish in roughly 16.7 ms at 60 FPS (and half that, ~8 ms, at 120 FPS). Now recall lesson 11: path tracing estimates the recursive integral ∫ fr Lii·n) dωi by sampling light paths. For IID finite-variance samples, standard error has the 1/√N baseline, so halving it needs four times the samples; low-discrepancy and reuse methods can improve practical behavior but do not make high-quality raw convergence free. A clean offline frame might spend hundreds to thousands of paths per pixel. At full HD, even 256 paths per pixel means about 5 × 10⁸ primary paths before their bounce rays. Typical real-time budgets therefore cannot drive the raw estimator to a clean offline error level without reconstruction and reuse.

回忆第 01 课的约束:实时一帧在 60 FPS 下必须在大约 16.7 毫秒 内画完(120 FPS 下则减半,~8 毫秒)。再回忆第 11 课:路径追踪通过采样光路来估计递归积分 ∫ fr Lii·n) dωi。对方差有限的 IID 样本,标准误差以 1/√N 为基线,因此减半需要四倍样本;低差异与复用方法能改善实践表现,却不会让高质量原始收敛变成免费。一帧干净的离线画面每像素可能花数百到数千条路径。在全高清下,仅每像素 256 条路径就约有 5 × 10⁸ 条主路径,尚未计算它们的反弹光线。因此典型实时预算若没有重建与复用,就无法把原始估计器压到干净离线图像的误差水平。

So real-time rendering chooses which error to tolerate and where to reuse work. Three recurring strategies organize this lesson:

因此实时渲染会选择容忍哪种误差、又在哪里复用工作。本课用三种反复出现的策略来组织这些方法:

Precompute · 预计算
bake it once, read it back (lightmaps, probes) — costs memory & assumes static烘焙一次、回读(光照贴图、探针)——耗内存、且假设静态
Approximate · 近似
substitute a cheap stand-in from data already on screen (SSAO, SSR)用屏幕上已有的数据换一个便宜的替身(SSAO、SSR)
Amortize · 摊销
spread the cost across frames — reuse last frame, converge over time (TAA, DDGI)把开销摊到多帧上——复用上一帧、随时间收敛(TAA、DDGI)

Keep this triple in view as a diagnostic. A shadow map precomputes the light's visibility for the current frame (§2). SSAO approximates ambient occlusion from the depth buffer (§3). Lightmaps precompute an indirect-light solution (§4). Temporal accumulation amortizes samples across frames (§5). Modern systems combine these with sparse ray tracing, importance sampling, spatial reuse, and learned reconstruction. The question is never “did it solve the equation?” in the abstract; it is “which estimator, bias, variance, failure support, latency, and temporal-stability contract did it choose?”

把这三元组当作诊断工具。阴影贴图为当前帧预计算光源可见性(§2);SSAO 从深度缓冲近似环境光遮蔽(§3);光照贴图预计算一份间接光解(§4);时序累积把样本跨帧摊销(§5)。现代系统还会把它们与稀疏光线追踪、重要性采样、空间复用和学习式重建结合。问题从来不是抽象地问“它是否解出了方程”,而是问“它选择了怎样的估计器、偏差、方差、失效支撑、延迟与时间稳定性契约?”

2 · Shadows via shadow mapping — a depth test from the light's eye用阴影贴图做阴影——从光源之眼做一次深度测试

A shadow is pure visibility toward a light: point x is lit if the light can see it, and shadowed if some closer surface blocks the view. Path tracing answers this with a shadow ray. Rasterization cannot shoot arbitrary rays cheaply — but it is superb at one thing: rendering depth from a viewpoint. So flip the viewpoint. Shadow mapping is a two-pass idea:

阴影本质上就是朝向光源的可见性:如果光源能看到点 x,它就被照亮;如果有更近的表面挡住了视线,它就在阴影里。路径追踪用一条阴影光线来回答。光栅化没法便宜地发射任意光线——但它极擅长一件事:从某个视点渲染深度。那就把视点翻过去。阴影贴图是一个两遍(two-pass)的想法:

lit(x)  ⟺  dlight(x)  ≤  zmap[ project(x) ]  +  bias

The whole subtlety hides in that + bias. The shadow map is a finite grid: each texel stores one depth for a little patch of surface, but the real surface under that texel slopes and spans a range of depths. So the stored value is a quantized, slightly-wrong estimate of the true depth. Compare a point against it naively and half the lit surface reports d(x) > zmap purely from that quantization error — the surface shadows itself in stripes. This is shadow acne.

全部的微妙都藏在那个 + 偏置 里。阴影贴图是一张有限的网格:每个纹素为一小片表面只存一个深度,可那纹素底下真实的表面是倾斜的、跨着一段深度范围。所以存下来的值是对真实深度的、量化过的、略有偏差的估计。若拿一个点朴素地去和它比,光照表面里会有一半仅仅因为这点量化误差就报出 d(x) > zmap——表面把自己投成了一条条纹的阴影。这就是阴影痤疮(shadow acne)

The fix is to nudge the comparison: add a small bias so a point must be meaningfully farther than the stored depth before it counts as shadowed. Too little bias and the acne stripes remain. But push the bias too high and you overshoot the other way: real contact shadows lift off, and an object's shadow visibly detaches from its base as if the object were floating — peter-panning (the shadow, like Peter Pan's, comes unstuck from the feet). Bias is a single knob trading one artifact against the other, and the widget below lets you feel exactly where the safe middle is.

解法是把比较推一下:加一个小小的偏置,让一个点必须明显地比存储深度更远,才算作被遮蔽。偏置太小,痤疮条纹还在。可偏置推得太高就矫枉过正到另一头:真实的接触阴影被抬起,物体的阴影会明显地从它的底部脱开,仿佛物体悬浮着——彼得潘(peter-panning)(阴影像彼得潘那样,从脚上松脱了)。偏置这一个旋钮在两种瑕疵之间权衡,下面的控件让你精确地感受到那个安全的中间地带在哪。

Slope-scaled bias, briefly斜率缩放偏置,简述

A constant bias is a compromise: surfaces nearly edge-on to the light need a large bias (their depth changes fast across one texel), while surfaces facing the light need almost none. The standard refinement is slope-scaled bias — scale the bias by how grazing the light angle is (roughly by tan of the angle between the surface normal and the light). This shrinks the peter-panning you pay on flat faces while still killing acne on steep ones. The widget uses a single flat receiver, so a constant bias suffices to show the trade cleanly.

常数偏移是一种折中:几乎与光线平行(掠射)的表面需要偏移(它们的深度在一个纹素内变化很快),而正对光的表面几乎不需要。标准的改进是斜率缩放偏移(slope-scaled bias)——按光照角度有多掠射来缩放偏移(大致按表面法线与光线夹角的 tan)。这在平面上减少了你要付出的彼得潘现象,同时仍能消灭陡面上的痤疮。本控件只用了一个平整的接收面,所以一个常数偏移就足以干净地展示这个取舍。

Two more pieces make shadow maps usable in practice. PCF (percentage-closer filtering) softens the hard, aliased shadow edge: instead of one depth comparison, sample the map at several neighboring texels, run the test on each, and average the pass/fail results. A point half-inside the penumbra comes back "60% lit," giving a soft edge instead of a jagged binary one. And cascaded shadow maps (CSM) handle large scenes: a single map spread over a whole outdoor level would give each texel a huge footprint (chunky shadows). CSM slices the view frustum by distance into a few cascades and gives each its own map — high resolution near the camera where you look, coarse far away where you don't.

还有两件事让阴影贴图在实践中可用。PCF(百分比渐近滤波)柔化那道生硬、走样的阴影边缘:不做单次深度比较,而是在邻近的几个纹素上采样该图、对每个都跑一遍测试、再把通过/未通过的结果平均。一个半陷在半影里的点会返回“照亮 60%”,从而得到柔和的边缘,而不是锯齿状的非黑即白。而级联阴影贴图(CSM)应对大场景:单张图铺满整个户外关卡,会让每个纹素覆盖一大片(块状阴影)。CSM 按距离把视锥切成几段级联、各给一张自己的图——相机近处(你看的地方)高分辨率,远处(你不看的地方)粗糙。

Shadow-map bias — acne vs peter-panning阴影贴图偏置——痤疮 vs 彼得潘
Side view. The light is up-left; the horizontal line is a flat receiver (the ground); the box is an occluder. The scene is baked into a coarse shadow map of only a handful of light-space depth texels (each stores one depth), so the lit ground has quantization error. For every point on the ground we compute its true light-space depth and compare to the stored texel depth + bias. Too little bias → the lit ground breaks into striped shadow acne (self-shadowing). Correct bias → a clean shadow anchored at the box's base. Too much bias → the shadow detaches from the box (peter-panning). Drag the bias.侧视图。光源在左上;水平线是一块平坦的接收面(地面);方块是遮挡物。场景被烘焙进一张粗糙的阴影贴图,只有寥寥几个光源空间深度纹素(每个存一个深度),所以被照亮的地面带有量化误差。对地面上的每个点,我们算出它真实的光源空间深度,与存储的纹素深度 + 偏置 相比。偏置太小 → 被照亮的地面裂成条纹状的阴影痤疮(自遮蔽)。偏置合适 → 一道锚在方块底部的干净阴影。偏置太大 → 阴影从方块脱开(彼得潘)。拖动偏置。
Bias
Artifact
Shadow-map texels
Lit ground misclassified
Show the core JS查看核心 JS
// Depth-compare-plus-bias, run per receiver point x.
// zMapAt(u): the coarse map's stored (quantized) light-space depth for the
//            texel that direction u falls in — one depth per texel.
// dLight(x): x's TRUE distance from the light along that same direction.
function isLit(x, bias){
  var u      = lightTexel(x);      // which shadow-map texel x projects to
  var stored = zMapAt(u);          // quantized nearest depth in that texel
  var d      = dLight(x);          // x's true light-space depth
  return d <= stored + bias;       // lit if not meaningfully behind the map
}
// bias too small  -> quantization makes lit ground read d > stored -> ACNE
// bias too large  -> points just past the occluder pass the test -> PETER-PANNING

3 · Ambient occlusion — how open is the sky here?环境光遮蔽——这里的天空有多开阔?

Split the incoming light Li into direct (from named light sources — handled by shadow maps) and ambient (a soft, everywhere glow standing in for all the indirect bounces we cannot afford). A crude but common ambient model just adds a constant to every surface. The problem: that constant floods creases, contact points, and cavities that should be darker because surrounding geometry blocks most of the sky. Ambient occlusion is the missing factor — for each point, what fraction of the hemisphere above it is open versus occluded by nearby surfaces. A corner where two walls meet is occluded, so it should be darker; an exposed flat is fully open.

把入射光 Li 拆成直接光(来自具名光源——由阴影贴图处理)与环境光(一层柔和、无处不在的辉光,替代所有我们负担不起的间接反弹)。一个粗糙但常见的环境光模型只是给每个表面加一个常数。问题在于:这个常数会漫进那些本该更暗的折缝、接触点与凹陷——因为周围的几何挡住了大部分天空。环境光遮蔽就是那个缺失的因子——对每个点,问它上方半球有多大比例是开阔的,又有多少被邻近表面遮蔽。两面墙相交的角落是被遮蔽的,故应更暗;一块暴露的平面则完全开阔。

Computing true occlusion means casting many rays over the hemisphere per point — again, too expensive per frame. SSAO (screen-space ambient occlusion) is the classic approximate trick: it never touches the real geometry. It reads the depth buffer — which the rasterizer already produced — and, around each pixel, samples a few nearby depth values. If many neighbors are closer to the camera than the surface here, this pixel sits in a pocket surrounded by geometry, so darken it; if neighbors fall away, it is open, so leave it bright. It is a purely 2.5-D estimate from data already on screen — which is exactly why it is cheap, and exactly why it has the same blind spot as everything screen-space (§5): it can only account for occluders the camera can see.

计算真实遮蔽意味着对每个点在半球上投出许多光线——同样,逐帧太贵。SSAO(屏幕空间环境光遮蔽)是经典的近似技巧:它根本不碰真实几何。它读取深度缓冲——那是光栅器已经产出的——在每个像素周围采样几个邻近的深度值。若许多邻居比此处表面更靠近相机,说明这个像素坐在被几何环绕的凹坑里,就把它压暗;若邻居纷纷退远,它就是开阔的,保持明亮。这是一个纯粹 2.5 维的、从屏幕已有数据得来的估计——这正是它便宜的原因,也正是它和一切屏幕空间方法(§5)有同样盲点的原因:它只能顾及相机看得见的遮挡物。

4 · Precomputed indirect light — radiosity, lightmaps, and probes预计算间接光——辐射度、光照贴图与探针

The hardest term is the recursive one: light that bounces off other surfaces before reaching x — indirect illumination, the soft color-bleeding fill that makes a scene look real. If the geometry and lights do not move, we can pay for it once, offline, and read the result back for free every frame. That is the precompute route, and it has a lineage.

最难的项是那个递归项:在到达 x 之前先从别的表面反弹过的光——间接光照,那种柔和的、渗色的补光,正是它让场景显得真实。如果几何与光源都不动,我们就可以一次性、离线地为它付账,之后每一帧免费回读结果。这就是预计算路线,它有一条谱系。

Radiosity is the classical method for the diffuse case. Break every surface into small patches; the light leaving patch i is its emission plus the light it receives from every other patch j, weighted by a form factor Fij that encodes how much of j's hemisphere i occupies (their mutual geometry — size, distance, orientation). That is a big linear system of patch radiosities; solve it once and you have full diffuse interreflection — soft, physically-based fill light. It is view-independent (diffuse light looks the same from every angle), which is exactly what makes the solution reusable.

辐射度(radiosity)是处理漫反射情形的经典方法。把每个表面拆成小面片;离开面片 i 的光,等于它自身的发射加上它从其他每个面片 j 收到的光,后者按一个形状因子 Fij 加权——该因子编码了 i 占据 j 半球的比例(它们相互的几何:大小、距离、朝向)。这是一个关于各面片辐射度的大型线性系统;解一次,你就得到完整的漫反射互反射——柔和的、基于物理的补光。它与视角无关(漫射光从任何角度看都一样),而这正是解可以复用的原因。

Lightmaps are how that precomputed result ships in a game. Bake the indirect (and often the static direct) illumination into a texture unwrapped over the static geometry; at runtime, shading a wall is just a texture fetch — nearly free, and gorgeous. The iron catch is in the word static: a lightmap is correct only for the geometry and lights it was baked with. Move a wall, open a door, or swing a light and the baked shadows and bounce lie. And crucially, lightmaps live on static surfaces — they say nothing about how to light a moving character walking through that baked room.

光照贴图(lightmaps)是那份预计算结果在游戏里的交付形式。把间接光(常常还有静态直接光)烘焙进一张在静态几何上展开的纹理;运行时,给一面墙着色只是一次纹理取样——几乎免费,而且极美。铁一般的坑就在静态二字:光照贴图只对烘焙时所用的几何与光源才正确。挪一面墙、开一扇门、或转动一盏灯,烘焙好的阴影与反弹就都在撒谎。而且关键在于,光照贴图长在静态表面上——它对如何照亮一个穿过那间烘焙房间的移动角色只字未提。

That gap is filled by irradiance probes (light probes). Scatter sample points through the volume of the scene; at each probe, precompute the light arriving from every direction and store it compactly. A dynamic object then reads the nearest probes and interpolates — so a character darkens as it walks into shade and picks up a red glow beside a red wall, all without per-frame bounce computation. The compact storage is the elegant part: incoming light over a sphere is a smooth low-frequency function, so we expand it in spherical harmonics (SH) and keep only the first few coefficients (often just 9, for the diffuse "L2" band). Those few numbers reconstruct the soft directional irradiance well enough for diffuse shading. Probes are precompute for the light field in space; lightmaps are precompute for it on surfaces — the pair covers static rooms and the dynamic actors moving through them.

这个空缺由辐照度探针(光照探针)填补。在场景体积里撒下采样点;在每个探针处,预计算从各个方向到来的光并紧凑地存下。动态物体随后读取最近的几个探针并插值——于是角色走进阴影会变暗、走到红墙边会染上一层红晕,全程无需逐帧计算反弹。紧凑存储是其精巧之处:球面上的入射光是一个平滑的低频函数,所以我们用球谐(SH)把它展开,只保留前几个系数(漫反射常常只用 9 个,即“L2”band)。这寥寥几个数就能重建出足够好的、柔和的方向性辐照度,用于漫反射着色。探针是对空间中光场的预计算;光照贴图是对表面上光场的预计算——二者搭配,覆盖了静态房间和穿行其中的动态角色。

TechniqueBuys which termVerbHandles dynamic?
Shadow mapdirect-light visibilityprecompute (per frame)yes (rebuilt each frame)
SSAOambient occlusionapproximate (screen-space)yes, but on-screen only
Lightmapindirect on surfacesprecompute (offline bake)no — static geometry & lights
Light probe + SHindirect on moving objectsprecompute (offline bake)dynamic objects, static lights
SSRglossy/mirror reflectionapproximate (screen-space)yes, but on-screen only
技术买下哪一项动词能处理动态吗
阴影贴图直接光可见性预计算(每帧)能(每帧重建)
SSAO环境光遮蔽近似(屏幕空间)能,但仅限屏幕上
光照贴图表面上的间接光预计算(离线烘焙)否——静态几何与光源
光照探针 + SH移动物体上的间接光预计算(离线烘焙)动态物体,静态光源
SSR光泽/镜面反射近似(屏幕空间)能,但仅限屏幕上

5 · Screen-space, and the new era屏幕空间,以及新纪元

SSR (screen-space reflections) fakes the mirror/glossy term the same way SSAO fakes occlusion: reuse the frame you already rendered. From a reflective pixel, reflect the view ray about the surface normal and march that ray through the depth buffer, stepping until it crosses a stored depth — a hit. Sample the already-shaded color there and blend it in as the reflection. When it works, you get gorgeous wet floors and glossy tabletops for the price of a screen-space raymarch, no extra scene traversal.

SSR(屏幕空间反射)伪造镜面/光泽项的方式,和 SSAO 伪造遮蔽如出一辙:复用你已经渲染好的这一帧。从一个反射像素出发,把视线光线关于表面法线反射,然后让那条光线在深度缓冲里步进,一步步走到它越过某个存储深度处——即一次命中。取那里已经着色好的颜色,作为反射混合进来。当它奏效时,你能以一次屏幕空间光线步进的代价换来极美的湿地板和光泽桌面,无需额外的场景遍历。

The screen-space blind spot屏幕空间的盲点

SSR, SSAO, and every screen-space method share one fundamental limitation: they can only use what is currently on screen. The depth buffer holds the visible surfaces and nothing else — so a reflection of the sky, of an object just off the edge of the frame, or of a surface hidden behind the reflector simply has no data to draw from. SSR characteristically fails at screen edges (reflections fade out) and cannot reflect anything the camera itself cannot see. It approximates the reflection integral using a 2-D shadow of the 3-D world; whatever that shadow omits, the reflection omits too.

SSR、SSAO 以及每一种屏幕空间方法都共享一个根本局限:它们只能用当前屏幕上有的东西。深度缓冲只保存可见表面、别无其他——所以对天空、对刚好落在画面边缘之外的物体、或对藏在反射体背后的表面的反射,根本没有数据可取。SSR 的典型失败发生在屏幕边缘(反射逐渐淡出),并且无法反射任何相机自己看不到的东西。它用三维世界的一张二维"影子"来近似反射积分;那张影子漏掉什么,反射就跟着漏掉什么。

This blind spot is precisely what the new era removes. Hardware ray tracing (lesson 10's BVH, now in silicon) lets a real-time renderer shoot a modest number of true rays per pixel into the actual scene — off-screen geometry included — for shadows, reflections, and one or two bounces of GI. The catch returns us to §1: a modest ray count is noisy. The unlock is pairing it with two of our three verbs — amortize across frames (reuse and accumulate samples over time) and ML denoising (a neural network trained to reconstruct a clean image from a sparse, noisy one). Schemes like DDGI (dynamic diffuse GI) go further: keep the light-probe idea from §4 but update the probes every frame with a few traced rays each, so the baked indirect light of lightmaps becomes fully dynamic — lights and geometry can move. This is the direct bridge to lesson 15, where real-time and offline rendering, split back in lesson 01, finally begin to converge.

这个盲点,正是新纪元所消除的。硬件光线追踪(第 10 课的 BVH,如今做进了芯片)让实时渲染器能向真实场景——包括屏幕外的几何——每像素射出为数不多的真光线,用于阴影、反射、以及一两次反弹的 GI。而问题又把我们带回 §1:光线数不多就有噪声。破局之道是把它与我们三个动词中的两个配对——跨帧摊销(随时间复用并累积样本)与 ML 去噪(一个被训练来从稀疏、含噪的图重建出干净图的神经网络)。像 DDGI(动态漫反射 GI) 这样的方案更进一步:保留 §4 的光照探针思想,但每帧用少量追踪光线更新探针,于是光照贴图那份烘焙好的间接光变得完全动态——光源与几何都能移动。这正是通往第 15 课的桥,在那里,第 01 课分开的实时与离线渲染,终于开始融合。

Where this points next接下来指向何处

We now have the real-time toolbox as a coherent set rather than a bag of tricks: techniques choose where to precompute, approximate, sample, reuse, and reconstruct. A high-sample reference path tracer can be an engineering reference under the same scene, material, spectral, and numerical model; it is not physical reality itself. But everything so far has assumed a frozen scene — one instant, held still while we shade it. Real content moves: characters walk, cameras pan, cloth billows. Lesson 13 leaves shading for animation and motion — how positions change over time, interpolation and easing, skeletal rigs and skinning, and why motion introduces its own sampling problem in time (the temporal cousin of the aliasing from lesson 06).

现在我们把实时工具箱看成一套连贯的体系、而非一袋子技巧:各种技术选择在哪里预计算近似采样复用重建。在相同场景、材质、光谱和数值模型下,高采样参考路径追踪器可以作为工程基准;它并不等于物理现实本身。但到目前为止,一切都假设场景是冻结的——一个瞬间,被定住让我们着色。真实内容会动:角色行走、相机横摇、布料翻卷。第 13 课离开着色,转向动画与运动——位置如何随时间变化、插值与缓动、骨骼绑定与蒙皮,以及为什么运动会在时间上引入它自己的采样问题(第 06 课走样在时间上的表亲)。

Takeaway要点

Typical real-time budgets cannot drive a raw path estimator to clean offline error each frame. For IID finite-variance samples, 1/√N is the standard-error baseline; practical systems therefore combine sparse samples with precomputation, approximation, and amortization, plus spatial reuse and reconstruction. Shadow maps cache the light's visibility as projected depth from the light's view, then test d(x) ≤ zmap + bias; too little bias gives acne, too much gives peter-panningPCF filters edges and cascades allocate resolution by range. SSAO approximates ambient occlusion from the depth buffer. Lightmaps bake indirect light onto static surfaces; light probes + spherical harmonics store a low-frequency field for dynamic objects. SSR marches the visible depth buffer and therefore misses off-screen information. Hardware ray tracing + ML denoising + DDGI spend more budget on dynamic transport while accepting their own bias, variance, and temporal-failure contracts.

典型实时预算无法在每一帧把原始路径估计器压到干净离线图像的误差水平。对方差有限的 IID 样本,1/√N 是标准误差基线;因此实践系统把稀疏样本与预计算近似摊销结合,并加入空间复用与重建。阴影贴图从光源视角把可见性缓存为投影深度,再测试 d(x) ≤ zmap + bias;偏置太小产生痤疮,太大产生彼得潘——PCF 过滤边缘,级联按距离分配分辨率。SSAO 从深度缓冲近似环境光遮蔽。光照贴图把间接光烘焙到静态表面上;光照探针 + 球谐存储供动态物体读取的低频场。SSR 沿可见深度缓冲步进,因此会漏掉屏外信息。硬件光追 + ML 去噪 + DDGI把更多预算用于动态光传输,同时也接受各自的偏差、方差与时序失效契约。

Interview prompts面试题