JamesB 发表于 2022-3-12 14:58

【Unity】批次合并理解和对比

【本篇是百人计划批次合并的备课内容,希望大佬们多指出错误,以防我误人子弟】
区分Batch | Drawcall | Set pass call


[*]Set pass call指一次渲染状态切换,材质不一致的时候出现一次
[*]两个相邻执行的Batch之间如果使用不同材质球或者使用同材质球不同pass则会执行一次Set pass call
[*]CPU调用一次GPU绘制函数称为一次Draw call,多个drawcall在unity中可以合并为一个Batch提交
[*]不同mesh不同材质会分别进行渲染设置并调用drawcall
[*]不同mesh同材质在满足条件的情况下被顶点数据合并一次性提交给GPU,减少batch不降低drawcall
[*]多pass的mesh每个pass会执行一个batch,无法合批
对于批次合并(动态合批/静态合批/gpu instancing/srp batch)的理解

如果要分清批次合并的作用,首先还是要了解一下Draw call这个东西的执行方式。Drawcall就是字面意思,提交(call)一次需要绘制(draw)的数据,画面是由GPU从显存提取数据渲染的,但是数据是CPU从内存中调取的。
这个机制比较像是取书,在绘制过程中,内存是书架,显存是桌子上可以同时放书的最大数量。一次draw call就是从书柜拿一次书。
动态合批的原理简而言之就是把符合条件(共享同一材质的多个模型)通过一次draw call绘制,这个模型数据有一定的限制,一次动态合批只能处理900个float4的数据
静态合批会把设置成static且材质相同的物体预先进行坐标转换,运行时不再需要进行顶点坐标变换操作,会产生额外资源,不会降低draw call。类似于你提前把需要一起拿的书放在柜子上临近的位置,这样再拿的是不需要一本一本书去找。
gpu instancing是把同材质同属性同Mesh的渲染对象一次性执行渲染,它单次渲染对象上限是1024个。
srp batch是在unity的新系统srp中才有的功能,它本质是通过减少相同信息在cpu/gpu之间的传输来打到优化的目的,它不减少draw call但是降低了draw call的切换成本,原理从官方shader支持srp batch的要求也可以看出来。unity要求shader将自用参数包裹在名为UnityPerMaterial的CBuffer语句中。在切换渲染状态(渲染对象)时,对无需修改数值的Buffer直接不进行更新操作,以此来减少单次Drawcall的带宽开销
整个了表做对比

实际使用感觉SRP Batch实在收效甚微 还超级影响Debug,只能说聊胜于无。GPU Instancing效果是最明显的,能用就多用
动态合批静态合批Gpu InstancingSRP Batch使用样例动态生成的同材质多条闪电Mesh场景中不会在运行时进行修改的、勾选Static的静态建筑草地原理将所有生效对象顶点在CPU中转换为世界空间将所有生效对象转换为世界空间,共享顶点与索引缓冲区只提交一个mesh和材质,但是提交多个实例的差异化信息,对同一个mesh在GPU进行变换绘制生效要求若干材质实例相同的动态对象静态对象(不会旋转移动或者缩放),具有相同的顶点属性同Mesh同材质对象所有Shader支持的对象合批上限(单批)不超过900个顶点属性(float4)且不超过300个verts64k vertices和64k indices(OpenGLES为48k indices,macOS为32k indices)1024个对象无Draw call变化↓-↓↓-打断原因1. 包含镜像(scale出现负值)
2. 使用不同材质实例3.存在光照贴图额外属性,比如光照贴图索引和缩放4. 延迟渲染或多pass前向渲染1. 状态修改(材质/坐标等信息)
2. 包含镜像(scale出现负值)穿插遮挡(比如在两个可供Instancing的Opaque物体A和B中插入一个需要判定遮挡的Opaque物体C)材质参数修改(MaterialPropertyBlock也不行)弱点生效要求多1. 需要对对象勾选Static Flag
2. 占用更多内存(相同对象不同引用会在运行时创建不同的副本)3. 项目设置中如果开启了Mesh优化,Unity会在构建生效对象的顶点缓冲区时删除所有未被任何着色器变体使用的顶点数据生效要求多1. 优化提升不明显
2. 在实际项目调试中会影响Frame Debugger内渲染条目的查看
页: [1]
查看完整版本: 【Unity】批次合并理解和对比