Unity GPU Instancing
GPU Instancing开启条件
首先Shader必须兼容与Instancing。
材质开启
Enable GPU Instancing
SRP Batcher的优先级高于GPU Instancing,对于Game Objects,如果SRP Batcher能被使用(Shader兼容SRP Batcher,节点本身也兼容等),则就会使用SRP Batcher,即便材质开启了Enable GPU Instancing也没用
如果SPR Batcher的条件被破坏,例如使用了MaterialPropertyBlock,且开启了Enable GPU Instancing,则GPU Instancing则会启用
GPU Instancing的性能
GPU Instancing对于顶点数比较少的模型不一定能提高性能,因为顶点数少时GPU不能充分的分配资源去绘制多个实例,这个顶点数的阈值根据不同显卡是不一样的,但一般来说少于256个顶点是不合适的。
如果有很多顶点少的物体需要绘制,可以将他们合并到一个mesh中进行绘制
自定义Shader兼容GPU Instancing

首先,定义PerMaterial Uniform block时,要使用INSTANCING相关的宏UNITY_INSTANCING_BUFFER_START,UNITY_INSTANCING_BUFFER_END和UNITY_DEFINE_INSTANCED_PROP。这些宏的作用是将Uniform block定义成数组。需要注意的是,只有当同一个材质下面的不同Instance存在逐Instance不同的属性时,才需要将UnityPerMaterial的CBuffer改成使用这些宏,否则是不需要的,因为这些宏只是为了将属性定义成数组,然后可以使用Instance索引去得到数组里面不同Instance各自的属性。另外,由于CBuffer的名字不能冲突,所以也不能仅仅将不同的属性单独拿出来使用这些宏包裹,如果需要拿出来就得全部拿出来,也就是将SRPBatcher使用的CBuffer的宏替换成这些宏
VS和FS的输入都要使用结构体作为参数,且结构体中需要使用宏UNITY_VERTEX_INPUT_INSTANCE_ID定义逐物体的instance id
在VS和FS中,都要使用宏UNITY_SETUP_INSTANCE_ID来设置instance id变量,这个宏的作用是使用一个base instance id和input中的instance id组合出一个instance id变量来作为数组索引获取相应的属性值
如果需要在FS中获取属性,则VS中需要使用宏UNITY_TRANSFER_INSTANCE_ID从input向output传递instance id。然后在FS中使用宏UNITY_ACCESS_INSTANCED_PROP获取属性。当然如果是在VS中获取所有属性进行计算,则不需要传递,直接在VS中使用宏UNITY_ACCESS_INSTANCED_PROP获取属性
另外,必须要添加#pragma multi_compile_instancing
