静态合并
渲染器本来就会把同一个网格的多份拷贝合成一次实例化绘制。它做不到的是把不同的网格 合成一次:每个网格在 GPU 里都是自己的一段内存,所以用五十种不同道具搭出来的关卡,每种材质 要花五十次绘制。
StaticBatch 就是为这个准备的。给一个不会动的网格加上它,游戏运行时,材质、贴图、
颜色和层都相同的网格会按区域合并成一个网格。
world.insert(wall, MeshRenderer, { mesh: 'builtin:cube', material });world.insert(wall, StaticBatch, {});在编辑器里,选中网格后在大纲的菜单里选静态合并。
- 网格按一次绘制拥有的全部状态分组 —— 材质、贴图、法线贴图、颜色、层、剔除与光照开关 —— 还可以用组件上的分组把两个房间分开。
- 每一组再按世界里的格子切开,所以一个批是一小片区域,剔除仍然有东西可剔。 一个格子里的顶点不超过 262,144 个。
- 被标记的实体保持原样:脚本照样能找到,碰撞体照样碰撞,编辑器照样能选中。只是它们的绘制 移到了合并后的网格上,那是另一个实体。
- 被合并之后,标记的网格不能再动。销毁是支持的(这个批会去掉它重新合并);移动不支持, 而且没有任何办法发现。
哪些会被留下
Section titled “哪些会被留下”合并不了的网格保持原样,并说明原因 —— 游戏运行时写在组件上,也写在性能分析器的静态合并 一节里。
| 原因 | 为什么 |
|---|---|
| 带骨骼 | 一次绘制只能处于一个姿态。 |
| 带形变 | 一次绘制只能处于一个形状。 |
| 细节层级 | 渲染器在运行时选择用哪一级。 |
| 半透明 | 结果取决于绘制顺序,而合并就是丢掉顺序。 |
| 会动 | 动态刚体或角色控制器:合并把网格站的位置烘进了顶点。 |
| 烘焙光照 | 场景有探针或烘焙,合并后的网格留不住每个部件各自的那一份。 |
| 同组只有一个 | 只合并一个网格什么也省不了,还多占内存。 |
合并会把每个部件的顶点复制进合并后的网格,所以它是拿内存换绘制。一个原本代表一百个实例的 部件,会变成一百份拷贝。性能分析器会为每个合并网格显示:它含多少部件、这些部件原本花多少 次绘制、这份拷贝占多少内存 —— 请把两个数字放在一起看。
同一个网格的许多拷贝用实例化,许多不同的网格用静态合并。