UPL6-4——GPU Instancing
UPL6-4——GPU Instancing
GPU Instancing
GPU Instancing 就是 GPU 实例化的意思,它是一种减少 Draw Call,提高渲染效率 的技术,主要用来批量绘制大量相同的网格(Mesh)对象
它的主要原理,当开启 GPU Instancing 后,Unity 会将一份 网格 和 材质 上传到 GPU,并且还会传递一批 实例数据(里面包含每个物体的位置、旋转、缩放、颜色等等)
GPU 收到数据后,会通过对象的实例化 ID 找到对应的参数,动态计算世界坐标,让 GPU 在一次 DrawCall 中绘制出许多相同的对象
说人话:GPU Instancing 利用 CPU 一次 DrawCall 告诉 GPU 的数据,GPU 自己根据数据绘制 N 个不同但是材质相同、网格相同的对象
比如:CPU 只通过一次 DrawCall 告诉 GPU 要绘制树,同时告诉了 GPU 这里 n 棵树的坐标、旋转、缩放、颜色等等数据,GPU 就利用这些数据批量的绘制 n 棵树
注意:
GPU Instancing 和 动态和静态批处理 的原理区别
动态和静态批处理,它们都需要在 CPU 端合并网格,再告诉 GPU,一个批次依然是一个大网格,这样在 CPU 端有 合并计算 和 内存 的开销
而 GPU Instancing 中 CPU 不会有太多额外开销(因为它只负责传递数据,并不再计算),而是把开销交给了 GPU
因为需要在 GPU 中根据数据进行更多矩阵运算,来绘制对象一个对象同时开启它们时,优先级为:静态批处理 > GPU Instancing > 动态批处理
Unity 还提供了相关 API 配合 GPU Instancing 使用
如何开启 GPU Instancing
在想要进行 GPU Instancing 对象的材质球中,勾选 Enable GPU Instancing,在 任意渲染管线 和 Shader 中都可使用

GPU Instancing 的使用限制
-
相同网格
所有想要进行 GPU Instancing 处理的对象必须使用同一网格
-
相同材质(颜色、额外属性可以变化;贴图、Shader 关键字不能变化)
所有对象必须使用同一材质,并且 Shader 必须支持 GPU Instancing
Unity 中默认 Shader 都支持它,如果是自定义 Shader,满足基本处理(不要求不同颜色等属性)只需要加入编译指令:#pragma multi_compile_instancing
如果想要支持不同颜色、金属度、透明度等等,可以查看官方文档:Creating shaders that support GPU instancing - Unity 手册 -
必须启用材质球上的 Enable GPU Instancing
-
不支持
SkinnedMeshRenderer(蒙皮网格渲染器)只支持
MeshRenderer 或者Graphics.RenderMesh等 API 绘制的网格
等等
适合使用 GPU Instancing 的情况
适合的情况
-
大量相同物体时
比如草地、森林、石头、瓦片、建筑模型、子弹 等等
-
实例之间只有少量差异
不同颜色或亮度、不同缩放比例、不同 UV 偏移等等
-
动态物体,但是网格和材质固定,性能瓶颈在 CPU 时
动态批处理对 CPU 开销大;静态批处理又不能移动,GPU Instancing 则既能支持移动,又减少 CPU 到 GPU 通信
等等
不适合的情况
-
每个物体的材质 / 贴图不同
GPU Instancing 要求材质一致,贴图差异会打断合批
-
实例数量很少(几十个以内)
这种情况 GPU Instancing 开销可能反而比 DrawCall 更大
-
大量独立的网格和材质
如果对象种类太多,GPU Instancing 没啥用
-
使用
SkinnedMeshRenderer(蒙皮网格渲染器)骨骼动画模型不支持 GPU Instancing
等等
