许多3D引擎都对动态批处理进行了较好的支持,使得使用相同材质的多个模型可以合并为同一个批次提交到 渲染,从而降低drawcall,充分利用GPU流水线,提升渲染效率。
垃圾box在2.0.0开始也尝试对此进行了支持,最开始的版本限制10顶点以内,2.0.2开始则移除了此限制,但不愧是垃圾box,2.0.2版本的动态合批与粒子系统产生了冲突,导致打包到微信的粒子位置修改无效,因此他们在2.1.0做了 反向优化,屏蔽掉了微信包的动态批处理,从而使得粒子能够正常使用,且与shader/批处理相关的一切优化,官方声明不在服务范围内(不充钱还想优化?)——不愧是你们啊。
回到文题,首先是自定义shader。一旦官方提供的基础材质达不到项目使用要求,就需要自定义材质和着色器。与此相关的部分在官网3d示例中有完整例子。
但完全拷贝这个自定义材质后就会发现,合并批处理并没有生效,但基础材质是可以合并的。检查源码后发现,需要在add函数中设置enableinstancing参数为true,才能使材质执行动态合批操作。
完成上述设置后,会发现原本能正常渲染的模型不见了,但统计数据显示savedRanderBatch计数有明显增加——合批生效了。
为什么模型不见了?原因在于使用批处理后,会提供一个GPU_INSTANCE的宏定义,使得着色器跳过重复计算,直接使用已经实例化过的材质的数据(目测指的就是第一个顶点),如果我们的自定义shader中并不使用这个宏,以及实例化后的数据,那么顶点的位置就无法计算了,自然也就渲染不出模型了。
因此需要在 自定义shader的顶点着色器脚本中加入