动态图形
在运行时控制 LOD、遮挡剔除与后处理,定位并缓解 GPU 侧动态渲染压力。
学习目标
- 能解释 Profiler / Frame Debugger 中 GPU ms 高时,如何区分 Vertex、Fragment(Overdraw)与 Post-processing 三类瓶颈
- 能说出 LOD Group、Occlusion Culling 与后处理 Volume 各自削减哪一类 GPU 成本,以及各自的启用前提
- 能回答:开放世界远景卡顿、室内转角仍绘制墙后物体、移动端后处理拖帧——你会先查 LOD、Occlusion 还是 Post Stack 中的哪一项?
原书边界:Chapter 6
Packt 第三版把本章命名为 Dynamic Graphics。官方目录列出的核心范围如下;这些条目共同构成本章的一对一边界:
- Exploring the Rendering Pipeline:纳入本章实验与验收,不拆到别章重复计数。
- Detecting performance issues:纳入本章实验与验收,不拆到别章重复计数。
- Rendering performance enhancements:纳入本章实验与验收,不拆到别章重复计数。
沿 CPU 提交、顶点、光栅、片元、带宽与后处理逐段定位瓶颈,再选择剔除、LOD、光照、阴影或 Shader 改动。Built-in、URP 与 HDRP 的工具入口不同,但先判 CPU/GPU bound、再缩小阶段的诊断顺序不变。 因此,本章既保留 2019/2020 语境,也明确标出迁移到现代 Unity 时哪些是稳定原理、哪些只是版本相关接口。
镜头一转远景就掉帧,GPU 在忙什么
你已经把 Draw Call 合批了、物理也睡了——帧率却在 拉远镜头看城市场景 或 打开全屏 Bloom + 景深 时掉到 40。Profiler 里 GPU ms 顶满 16.6ms 预算,CPU 却还有余量。这不是提交慢,而是 显卡在顶点、像素或后处理上算不过来。
上一章物理是 CPU 侧;这章要解决的,是 运行时仍随镜头、距离、特效变化的 GPU 账单。目标不是关掉画面,而是 远处换简模、被挡的不画、用不上的后处理别每帧全屏算。
像摄影棚灯光:近景精修,远景只留轮廓
想象拍外景:近处演员 要高清妆容与布料褶皱;百米外的楼群 观众看不清窗框,只要 silhouette 对就行。若远处仍用近景道具、还把被墙挡住的布景也打光渲染,灯光师(GPU)会烧断保险丝。
这章的三把剪刀——LOD、遮挡剔除、后处理分级——都是按「观众真的看得到吗」动态减工作量。
GPU 瓶颈:先分清卡在管线哪一段
Ch1 你已会用 Profiler 对比 CPU ms 与 GPU ms。当 GPU bound 时,下一步不是继续合批,而是看 GPU 在干什么。
↡图形处理器执行顶点变换、光栅化、像素着色与后处理全屏 Pass 的总耗时;Profiler GPU 模块或 Render Thread 可观测。 在 Frame Debugger 里体现为 一串自上而下执行的 Render Pass。常见三类热点:
- Vertex / 几何:Stats 里 Triangles、Vertices 极高——远景仍提交高面数、大量 Skinned Mesh
- Fragment / Fill:Overdraw 高——半透明粒子叠层、UI 全屏、大分辨率
- Post-processing:Volume 里 Bloom、DOF、SSR 等多 Pass 全屏
LOD Group:远处换简模
↡Level of Detail:按与相机距离切换不同精度网格,近高远低,超出最大距离可完全不渲染。 由 LOD Group 组件管理:每个级别绑定一个 Renderer(或子物体),Inspector 里设置 Screen Relative Height 或 Distance 切换阈值。
配置要点
- LOD0 保留玩家能看清的细节;LOD2 可用极简 proxy 或 impostor
- 最后一级可设为 Culled,超出距离 0 Draw Call
- 跨级 pop 明显时:启用 Fade Mode(Cross Fade / Speed Tree)或略重叠阈值(hysteresis)
- Skinned Mesh 也支持 LOD,但切换时注意动画是否共用同一 Avatar
Occlusion Culling:被墙挡住的别画
↡视锥剔除:相机视锥外的物体不提交。遮挡剔除:视锥内但被静态遮挡物挡住的物体也不提交。 解决 Frustum Culling 管不到 的情况:转角后整栋楼的 Renderer 仍在视锥内,却被墙体完全挡住。
未烘焙或未启用时,墙后物体 仍会 Draw,浪费 Vertex 与 Overdraw。
启用后需 烘焙 Occlusion 数据(Window → Rendering → Occlusion Culling):标记 Occluder Static 的墙体参与遮挡,Occludee 物体被写入剔除单元。适合 室内、走廊、城市峡谷 等静态遮挡丰富的场景;开放平原收益有限。
后处理栈:全屏 Pass 叠加
↡渲染完不透明/透明物体后,对整帧图像依次施加 Bloom、DOF、Color Grading 等效果的 Volume 管线。 在 URP/HDRP 中由 Volume Profile 驱动。每个 Effect 多为 至少一次全屏 Draw,分辨率越高、Pass 越多,Fragment 带宽 越贵。
移动端常见策略:全局 Volume 只留 Tonemap + 轻 Bloom;DOF / Motion Blur / SSR 按 Quality Level 或场景局部 Volume 开关。Profiler 里逐项 禁用 Volume Override 对比 GPU ms,比凭感觉调参快。
粒子与 LineRenderer:动态生成的 GPU 税
↡Particle System 与 LineRenderer 每帧重建或更新网格,常触发 Dynamic Batching 失败与大量透明 Overdraw。 不属于静态 LOD/Occlusion 能覆盖的范围——它们 每帧变,且多为 半透明、从近到远叠满屏幕。
动手:GPU 动态图形排查
下面五步把「GPU bound + 镜头相关卡顿」从定位到改动走通。每切一步,示意图对应当前关注点——建议在卡顿镜头下同步打开 Profiler GPU 与 Frame Debugger。
猜一猜:拉远镜头 Tris 几乎不变,和 Tris 随距离明显下降,分别更该先查 LOD 还是 Occlusion?
① 基线:确认 GPU bound 与 Stats 读数
Play 卡顿场景,Profiler 对比 CPU ms 与 GPU ms。Game Stats 记下 Tris、Batches、SetPass;GPU 更高则本清单有效。Frame Debugger 看 Pass 列表哪段最长。
容易踩的坑
小结
- GPU bound 时先分 Vertex(Tris)/ Fragment(Overdraw)/ Post 三类瓶颈
- LOD Group 按距离降面数或 Culled;需真实多级网格与合理阈值
- Occlusion Culling 剔除视锥内被挡静态物;需烘焙,适合室内/城市
- 后处理栈 每层≈全屏 Pass;按平台分级 Volume,逐项 Profiler 对比
- 粒子 / LineRenderer 动态透明叠层是常见 Fill bound;限数量、并材质、降更新
练习
问题 1(改 Demo 型) 在 GPU ms 最高的镜头打开 Stats,记下 Tris 与 Batches。任选 为一个重复 Prefab 加 LOD Group 或 烘焙 Occlusion 一个小室内 只做一处改动,同镜头复测——GPU ms 与 Tris 变化多少?
问题 2(问答型) Frustum Culling 与 Occlusion Culling 各剔除哪类物体?为何开放平原 Occlusion 收益小?
问题 3(问答型) 后处理 Bloom 为何比 Color Grading 更耗 GPU?移动端常如何取舍?
名词解释
本章出现的专业名词,用大白话再讲一遍。
- LOD(细节层次)
按与相机距离切换网格精度。详见 LodTransitionDiagram 与 LOD Group Stepper。
- LOD Group
管理多级 Renderer 与切换阈值的组件。详见 LodTransitionDiagram。
- Occlusion Culling(遮挡剔除)
剔除视锥内被静态遮挡物挡住的物体。详见 OcclusionCullingDiagram mode on。
- Frustum Culling(视锥剔除)
相机视锥外物体不提交;引擎默认开启,与 Occlusion 互补。
- Post-processing Stack(后处理栈)
渲染完成后依次施加的全屏效果链。详见 PostProcessStackDiagram。
- Overdraw
同一像素被多次绘制;Stats 与 Fragment bound 的关键指标。详见 RenderingPipelineGpuDiagram highlight fragment。
- Volume Profile
URP/HDRP 中挂载后处理参数的 ScriptableObject,可按全局/局部/Quality 分级。