移动 GPU 与桌面 GPU 是两种架构哲学。本文深入基于瓦片的渲染(TBR/TBDR),解释它为何是移动端性能的地基。
移动 SoC 的 GPU 与 CPU 共享同一块系统内存,内存带宽远小于桌面独显,且访问外部内存极其耗电(发热、降频的主因)。所以移动 GPU 的设计目标是:尽量少访问外部内存。TBR/TBDR 正是为此而生。
移动 GPU 与桌面 GPU 是两种架构哲学。本文深入基于瓦片的渲染(TBR/TBDR),解释它为何是移动端性能的地基。
移动 SoC 的 GPU 与 CPU 共享同一块系统内存,内存带宽远小于桌面独显,且访问外部内存极其耗电(发热、降频的主因)。所以移动 GPU 的设计目标是:尽量少访问外部内存。TBR/TBDR 正是为此而生。
本文基于 Unity 6.3 LTS(6000.3)URP 官方手册核对撰写(Enable the GPU Resident Drawer in URP / Make a GameObject compatible / Enable GPU occlusion culling in URP)。内容面向 URP;HDRP 亦有相关能力,但本文以 URP 官方文档为准。
GPU Resident Drawer 会自动使用 BatchRendererGroup(BRG)API,以 GPU 实例化(GPU instancing) 的方式绘制场景中的 GameObject,从而减少 Draw Call 数量、释放 CPU 处理时间。
Shader 变体爆炸(Shader Variant Explosion) 是现代游戏引擎渲染中最棘手的工程问题之一。一个功能丰富的材质 Shader,为了支持各种开关(有无法线贴图、有无阴影、光源类型、雾效、蒙皮……),往往需要编译出成千上万甚至上百万个变体。
核心关注两个问题:
一个点收到的光分两部分:
全局光照 = 模拟间接光(多次弹跳)。它是"真实感"的关键,但也是最贵的部分(真正的多次弹跳是全局积分问题)。实时渲染的所有 GI 方案,本质都是在质量、动态性、性能之间做近似与取舍。
主渲染得到的是一张(通常是 HDR 的)图像;后处理把它当作输入,用一连串全屏 Pass 施加效果(Bloom、色调映射、DOF、颜色分级…),最终产出呈现给屏幕的图像。
关键顺序原则:
- Bloom 在色调映射之前(需在 HDR 线性空间提取高亮)。
- 色调映射把 HDR 压到 LDR,是分水岭。
- 颜色分级通常在色调映射之后(对 LDR 调色,或用 LUT)。
- TAA 通常更靠前(在主渲染阶段解析);FXAA 等纯后处理 AA 靠后。
- UI 在后处理之后叠加,避免被模糊/调色污染。
下图从像素级别展示了锯齿的产生原因以及四种代表性方法的消除思路:
渲染管线(Rendering Pipeline) 是引擎把 3D 场景数据转换成屏幕上 2D 图像的整个流程。它决定了引擎如何组织光照、如何处理几何、如何在画质与性能之间权衡,是渲染架构中最顶层的设计决策。
渲染管线分为两个层次:
提示
显示器与人眼对亮度是非线性感知的,但光是线性叠加的——光照计算必须在线性空间进行。Gamma/sRGB 转换一旦出错,"光照发灰、阴影过暗、加法不对"等经典 bug 接踵而至。色彩管理就是把这个转换理清楚。
pow(x, 1/2.2)),暗部精度高;显示时再解码回线性亮度。以 UE5 Nanite 为主要范例,探究"虚拟化几何"这一现代渲染范式。
虚拟几何体借鉴了虚拟纹理(Virtual Texturing) 的思想:
虚拟纹理之于贴图,就是虚拟几何之于网格 —— 只加载、只处理当前视角下真正可见、且在该分辨率下真正需要的那部分数据。
传统渲染里,一个模型的全部三角形都要提交给 GPU,再靠离散 LOD 切换降负载。虚拟几何则把网格切成大量小簇(cluster),运行时按屏幕需要动态选择每一簇的精度、流式加载、GPU 驱动剔除,让画面里始终维持"每个三角形约 1 像素"的理想密度 —— 无论模型原始面数是几百万还是几十亿。
游戏的纹理总量可达数十上百 GB,远超显存。虚拟纹理借鉴虚拟内存的思想:
把一张(或全部)巨大纹理在逻辑上视为完整的,但物理上只把当前帧真正采样到的小块(page/tile)驻留显存,其余留在磁盘/内存按需换入。显存占用与纹理总量解耦。
类比操作系统的虚拟内存:逻辑地址空间很大,物理内存有限,靠页表 + 缺页换入。
| 结构 | 作用 |
|---|---|
| 页(Page / Tile) | 把大纹理切成固定小块(如 128×128),流式与驻留的最小单位 |
| 页表(Page Table / Indirection Texture) | 记录"逻辑页 → 物理页缓存中的位置"的映射,本身是一张小的间接纹理 |
| 物理纹理(Physical Texture) | 显存中一块固定大小的图集,存放当前驻留的页 |