简而言之: 密集植被很少单靠三角形数被杀死——它死于上千次 draw call、粗心 alpha 卡片的过绘制,以及没人记得还开着 的阴影。把力气按这个顺序花:先实例化,次剔除距离,三阴影,四 LOD,五密度摆放——并用同一台固定相机、每次只动一个变量地 验证每一步,否则你什么都学不到。本指南逐段配上那个告诉你"这就是你的问题"的剖析器特征。
真实的森林"免费"渲染,因为物理是大规模并行的。你的 GPU 能在 60 fps 伪造那份观感——但前提是你别再打败引擎为这活儿早就 自带的机器。
## 心智模型:五个瓶颈,一个顺序
植被性能不是一个问题,是五个,且它们以可预测的次序主导。draw call 先绑住 CPU;剔除距离决定你到底让 GPU 画多少;阴影 悄悄把每一个投射它们之物的开销翻倍;LOD 与过绘制统治逐像素的账单;密度摆放决定这一切你到底需要多少。乱序去攻,你就会优化 一个本不是瓶颈的东西。下面的顺序,就是开销真正咬人的顺序。
## 先实例化,其余一切在后
一棵树画 5000 次,比 5000 棵各自独立的树便宜得离谱——两个引擎都把重复网格批处理为实例化绘制,你的头一件事 就是别去打败那台机器。
Unreal 通过 foliage 和层级实例化静态网格批处理;Unity 通过 GPU 实例化和地形细节。悄悄打破批处理的:
- 植被被放置为唯一的 actor/对象而非实例;
- 逐实例的材质变体——用一个材质里的逐实例数据(颜色、缩放),而非为每种观感各写一个材质;
- 摆放在组织上分散,使引擎无法把簇作为单位剔除。
剖析器的破绽毫不含糊:draw call 随植株数量而增。若一个森林视角显示成千上万次 draw call,先修这个再碰别的——这份清单里 再往下的一切都救不了你,因为在 GPU 还没起步之前你就已 CPU 受限。健康的实例化植被,对整个森林视角把 draw call 保持在 低三位数,无论里面有几千株植物。
## 剔除距离是白捡的钱
草不需要在 800 米外渲染——设逐类型的剔除距离(地被 30–60 米、灌木 100–200 米,只有树木配得上远距离),配上 淡出范围以掩盖弹出。
这是整条管线里每分钟价值最高的设置,却因为默认在那儿又没人注意,被例行地留在"无限"。理由是知觉性的:地被远在 100 米前就 张不足一个像素——它对最终画面字面上一无贡献,却仍每帧花费顶点、过绘制和阴影工作。远处覆盖属于更便宜的系统:地形材质的 颜色、不透明的 impostor,或者干脆是涂成正确绿色的地形层远 LOD。
淡出范围(抖动或 alpha)掩盖弹出,让玩家永远看不见剔除距离本身。把淡出调到恰好长到隐形、不再更长——过长的淡出意味着在交叉 淡化期间你为同一株植物的两个表示付了钱。
## 阴影:账单里沉默的那一半
为小地被关掉动态阴影投射,为树木保留,为灌木按距离限制——草的阴影以近乎零的视觉收益把你的开销翻倍。
阴影通道里每一片草叶都从光源视角再画一遍。在密集场景里阴影通道常常与基础通道一样贵——这意味着草的阴影可能是整份植被 预算里最大的单项,却在视觉上与草丛根部一抹简单的环境变暗无从区分。修复几乎免费:地被关闭阴影投射,树木开启(它们的阴影 做真正的构图工作),中间者按距离限制。然后在剖析器里前后对照阴影通道——它通常是实例化之后最大的单项胜利,且只需几分钟。
## LOD:给轮廓做预算,而非多边形
好的植被 LOD 链保留外形、屠戮内部——用眼睛验证过渡距离,并把 impostor 之前最后那个网格 LOD 优化得最狠,因为 那是每个大远景里都在屏幕上的那一个。
像这样的地层植物,正是剔除距离与阴影设置回报最大之处——成千上万个实例,每个在几十米开外几乎毫无贡献,每个若投射动态阴影 便开销翻倍。
英雄树的一条实用链:完整网格 → 内部约 50% 削减(同一轮廓)→ 合并卡片约 15% → 不透明 impostor/billboard。两条能省真痛的 注记:
- 即便在带虚拟化几何的引擎里,远处的 impostor 仍然值得,因为无论三角形怎么付费,过绘制与阴影都仍是真实开销。虚拟化 几何解决三角形数量,而非透明度开销。
- 透明是远距离的敌人。密集的 alpha-tested 卡片恰好在 GPU 最弱之处——中段 LOD——堆起过绘制。近处偏爱网格叶片,远处偏爱 不透明 impostor;重 alpha 的中段正是帧时间藏身之处。若某一个 LOD 神秘地贵,那几乎总是透明的那个。
## 过绘制:你看不见的开销
过绘制是 GPU 透过层叠的透明表面把同一像素着色多次——植被特有的诅咒,在最终画面里不可见,且往往是一个"轻" 场景之所以慢的原因。
多数引擎都有过绘制可视化模式;打开它,看一片草地。若它发白光,你就是在把每个像素着色五到十次,随着重叠的 alpha 卡片 层层堆积。缓解手段:更少更大的草叶,而非许多细的;轮廓允许处用不透明几何;以及对贡献最少的卡片做激进剔除。过绘制正是 "我的场景很慢但没什么看着贵"的经典元凶,因为三角形便宜,而像素被反复付费。
## 密度是设计决定,不是滑块位置
玩家走动与观看处密,别处疏——沿小径一条 20 米宽的丰富细节带,以均匀成本的零头读作"处处茂盛"。
坡度与高度遮罩自动做了一部分(陡面与远处台地根本不需要地被),成簇做了其余——带空隙的簇比均匀填充渲染更便宜且看着更 自然,于是性能上的胜利与美感上的胜利指向同一方向。这里摆放工具挣回自身价值:用遮罩与逐物种规则刷密度,再直接烘焙为引擎 原生实例,正是一个下午与一周之差。这是Numivo 的散布所做的核心——而且因为它烘焙为普通 foliage 与实例化 网格,本文的每项技法都原封不动地适用于结果。你与标准优化之间没有插件运行时;烘焙好的场景就是引擎内容。
## 性能剖析循环
同一相机、同一视角、每次一个变量——每次改动后测量 GPU 帧时间、draw call、阴影通道与过绘制。
在你最密的远景里选一台固定的"预算相机",在上面每一步前后对统计截图。纪律之所以要紧,是因为植被优化会相互作用:一次 剔除距离改动会改变阴影通道看到多少实例;一次 LOD 改动会改变过绘制;一次密度改动一次性改变它们全部。随机漫游产出随机数字, 以及关于某项改动是否有用的不可证伪的争论。固定相机产出你能为之辩护的决定。把数字存进一张共享表,趋势线会讲出单次测量讲 不出的故事。
## 值得偷师的现场数字
- 地被剔除:30–60 米 · 灌木:100–200 米 · 树木:视线
- 一个健康的实例化森林视角的 draw call:低三位数
- 密集场景里阴影通道的占比:常达植被开销的约一半——关掉草的阴影是现存最便宜的大胜利
- 读作"处处茂盛"的小径带陈设宽度:约 20 米
- 一棵英雄树的 LOD 数:3 个网格 LOD + 不透明 impostor
- 草的过绘制目标:在过绘制视图里少于约 3×,而非层叠 alpha 卡片那种发白的 8–10×
## 迷你 FAQ
Nanite / 虚拟化几何是否让这一切过时? 它改变哪些条目主导,而非改变纪律。alpha 卡片的过绘制、阴影开销、逐实例开销 全都还在,远处的 impostor 仍然值。请在你的目标硬件上测量,而非假定新技术解决了你那个具体瓶颈——它也许只是把它挪走了, 而非移除了。
为什么我的场景连低密度也慢? 老嫌疑犯,按序:投射动态阴影的草、打败批处理的逐变体唯一材质、无限的剔除距离,或者 堆过绘制的 alpha-tested LOD 链。每个都有独特的剖析器特征——改之前先查,否则你会修错那个。
对玩法而言多密算"太密"? 战斗可读性在性能之前先给密度封顶:若剪影没入杂乱,玩家怪游戏,而非怪陈设。远景密、竞技场 适中,正是同时熬过剖析器与试玩的那套模式。
该烘焙还是保持程序化? 出货就烘焙——烘焙好的实例诚实地剖析,且不带运行时依赖地出货。把程序化设置(遮罩、规则、种子) 留在版本控制里,好让你在地形改动后重烘焙,而无需手工重做那份工。
看着密又快并不矛盾——它多半是把五件事按正确顺序做、并用同一台相机逐一证明的那份纪律。