GPU Gems 2 · Chapter 9. Deferred Shading in S.T.A.L.K.E.R.

以 G-buffer 和 MRT 把几何属性与动态光照分开,再用光源剔除、stencil mask、材质索引与 shadow map 控制屏幕空间成本。

学习目标

  • 能说明 deferred shading 如何把 geometry pass、G-buffer 和 lighting pass 分开
  • 能为位置、法线、albedo、gloss、material ID 与 ambient occlusion 设计 MRT 布局
  • 能用光源剔除和 stencil mask 限制真正受影响的屏幕像素,并识别阴影造成的额外成本
  • 能解释透明 primitive 为什么通常走 forward fallback,以及虚拟位置如何改善 parallax 的光照一致性

forward renderer 在每个物体 pass 中重复做顶点变换、纹理过滤、法线解压和材质计算。将几何与光照解耦:geometry pass 只输出后续需要的属性,lighting pass 读取这些属性为像素累积光照。

Forward:object × lights vs Deferred:geometry → G-buffer → lightsforward shadingobject 1light workobject 2light workobject 3light workobject 4light workdeferred shadingG-bufferlights屏幕空间处理降低 CPU / vertex 重复工作
deferred shading 把几何与光照解耦:同一个可见像素的法线、位置和材质属性只生成一次。

1. G-buffer 与 MRT

可以放 eye-space position、normal、albedo、gloss、material ID 和 ambient occlusion。DirectX 9 的 MRT 允许一次 geometry pass 写多个 render target,但每个额外通道都会增加显存带宽和后续采样。

的布局应从 lighting shader 反推,而不是按“能放多少就放多少”。法线可以编码在 32-bit 或浮点格式中,position 可能需要更高精度;material ID 与 gloss 可以占用空余组件,帮助 light shader 选择不同响应函数。

G-buffer:一次 geometry pass,保存多种光照输入positioneye-space positionMRT target 0normalsurface normalMRT target 1albedo + glossbase color specularMRT target 2material + AOlight response controlsMRT target 3布局是质量、带宽、解码成本和材质灵活性的折中
MRT 的每个通道都要服务后续 lighting;剩余组件可以编码材质 ID、gloss 或 AO 等控制量。

2. Lighting pass 的屏幕空间预算

的理论成本与光源覆盖的屏幕区域相关,而不是与场景中所有物体的数量直接相关。先用 sector/portal、CPU 或 GPU occlusion culling 减少候选光源,再用光源体积和 stencil mask 限制像素。

Lighting pass:只给受影响的像素算光G-bufferpositionnormalmaterial / AOlight cullingsector / portalCPU / GPU occlusionlight volumestencilaffectedpixels onlyaccumulate光照成本随屏幕影响区域增长,而不是随所有物体重复增长
光源不必覆盖全屏;层次剔除、occlusion query 和 stencil mask 共同限制实际 shading 区域。

shadow-casting light 还要生成或采样 shadow map,通常是最大的额外成本。艺术决策也很关键:并非每盏模拟环境光的灯都需要阴影或 glossy specular;将不必要的 shadow light 降为 unshadowed light,收益往往比继续微调 shader 更直接。

3. 太阳、AO 与虚拟位置

方向光常覆盖很大的屏幕区域,但仍可以用 sky mask、背向太阳的 normal 和 AO 为零的像素做 stencil 过滤。先快速标记不可能被太阳照亮的像素,再让复杂 shadow filtering 只运行在剩余区域。

可以改善近距离 parallax 的阴影边界和 surface acne,但它是视觉近似,不能把它当成真实几何位移。位置、法线和 height 的编码必须保持一致,否则光源方向变化时会出现不稳定的阴影。

4. 材质响应与透明边界

deferred 的材质系统通常把 lighting shader 需要的控制量写进 G-buffer,例如 material index、gloss 和 AO;light shader 可以据此查 2D/3D lookup table,而不是为每种材质组合生成一套 shader。这将“材质改变光照响应”反过来组织成“光照读取材质参数”。

Deferred 的边界:透明需要另一条路径opaqueone surface → G-buffermany lights → 2D passtransparentmultiple layers / orderforward fallback
G-buffer 通常每像素保存一层表面;透明需要多层排序或深度 peeling,因此常保留单独 forward 路径。

透明是架构边界:单层 G-buffer 没有空间保存多个深度排序的透明表面。实际系统可以让透明 primitive 走 forward lighting,通常不共享 deferred 的 shadow 处理;关键是把这条 fallback 当成显式的渲染路径,而不是偷偷覆盖 G-buffer。

5. 动手实验:成本随哪一维增长

调高光源数量,观察 lighting pass 和 stencil affected pixels 增长;调高 overdraw,观察 geometry/G-buffer 固定成本上升;切换 shadow-heavy,观察同一受影响区域的光照成本被放大。数值只是趋势示意,真实结论要回到 GPU profile。

Deferred shading 实验

比较固定 geometry/G-buffer 成本与受屏幕影响的 lighting 成本。

frame passes · balancedstencil affected pixels:61%G-buffer 32lighting 61post-process趋势示意,不替代真实 GPU profile

增加光源主要提高 lighting pass;增加 overdraw 主要提高 geometry/G-buffer 成本。阴影质量会放大受影响像素的代价。

小结

  • deferred shading 用 geometry pass 写 G-buffer,再在 lighting pass 读取属性累积光照。
  • MRT layout 是精度、带宽、解码和材质灵活性的折中。
  • 光源剔除与 stencil mask 将 lighting 限制到真正受影响的屏幕区域。
  • 阴影、G-buffer 带宽和 overdraw 仍可能成为瓶颈,架构选择必须依赖 profile。
  • 透明不适合单层 G-buffer,通常需要 forward fallback;virtual position 只是局部视觉近似。

练习

问题 1|pass 设计 geometry pass 为什么不直接计算所有动态光照,而是把 position 和 normal 写入 G-buffer?

问题 2|通道预算 如果一个 G-buffer 通道还有空余组件,哪些字段适合放进去?放进去前还要检查什么?

问题 3|透明 为什么一层 G-buffer 不能自然表达多个半透明表面?工程上如何处理?

名词解释

本章出现的专业名词,用大白话再讲一遍。

deferred shading
先写表面属性、后按屏幕像素计算光照的渲染架构。
G-buffer
保存位置、法线、颜色和材质控制字段的中间缓冲集合。
MRT
一个 pass 同时写多个 render target 的输出机制。
lighting pass
读取 G-buffer 并累积动态光照的后续阶段。
stencil mask
标记光源实际影响像素、限制后续 shading 范围的掩码。
virtual position
沿法线轻微移动 G-buffer 位置以改善 parallax 光照近似的方法。

资料与写作方式声明

本章以GPU Gems 2 · Chapter 9. Deferred Shading in S.T.A.L.K.E.R.权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…