Unity动态合批(Dynamic Batching)与静态合批(Static Batching)

动态合批与静态合批其本质是对将多次绘制请求,在允许的条件下进行合并处理,减少cpu对gpu绘制请求的次数,达到提高性能的目的。

1.静态合批是将静态(不移动)GameObjects组合成大网格,然后进行绘制。静态合批使用比较简单,PlayerSettings中开启static batching,然后对需要静态合批物体的Static打钩即可,unity会自动合并被标记为static的对象,前提它们共享相同的材质,并且不移动,被标记为static的物体不能在游戏中移动,旋转或缩放。但是静态批处理需要额外的内存来存储合并的几何体。注意如果多个GameObject在静态批处理之前共享相同的几何体,则会在编辑器或运行时为每个GameObject创建几何体的副本,这会增大内存的开销。例如,在密集的森林级别将树标记为静态可能会产生严重的内存影响。此时就必须去权衡利弊,为了更少的内存占用,可能需要避免某些GameObjects的静态批处理,尽管这必须要牺牲一定的渲染性能。
静态合批在大多数平台上的限制是64k顶点和64k索引(OpenGLES上是48k索引,macOS上是32k索引)。

2.动态合批是将一些足够小的网格,在CPU上转换它们的顶点,将许多相似的顶点组合在一起,并一次性绘制它们。
无论静态还是动态合批都要求使用相同的材质,动态合批有以下限制:

  • 动态合批处理动态的GameObjects的每个顶点都有一定的开销,因此动态合批处理仅应用于包含不超过900个顶点和不超过300个顶点的网格。

    • 如果shader中使用Vertex Position, Normal和single UV,可以批量处理最多300个顶点,而如果shader中使用Vertex Position, Normal, UV0, UV1和Tangent,则只能使用180个顶点。
    • 注意:将来可能会更改属性计数限制。
  • 如果GameObjects在Transform上包含镜像,则不会对其进行动态合批处理(例如,scale 为1的GameObject A和scale为-1的GameObject B无法一起动态合批处理)。

    • 为了验证此说法,笔者亲自做了测试,对于两个同样的物体:
      a.一个物体保持scale为(1,1,1),改变另一个物体的scale:
      1).当三个轴向的缩放值为负数(简称负缩放)的个数为偶数时可以合批处理,即scale为(1,1,1)和scale为(-1,-2,3)、(-1,2,-3)、(2,-3,-4),此时三个轴向的负缩放的个数为0个、2个、2个和2个,均为偶数个,可以合批处理,注意正负号,缩放数值可以随便更改;
      2).当三个轴向的负缩放的个数为奇数时可以不能合批处理,即scale为(-1,1,1)、(1,-2,3)、(1,2,-3)和(-2,-3,-4),此时三个轴向的负缩放的个数为1个、1个、1个和3个,均为奇数个,不可以合批处理。
      b.同时改变两个物体的缩放,仍然符合上述的三个轴向的负缩放的个数为奇数个时不合批,偶数个时合批:
      1).A物体(1,2,3),B物体(-1,2,3)、(1,-2,3)、(1,2,-3),奇数个负缩放不合批
      2).A物体(-1,2,3),B物体(-1,2,3),奇数个负缩放不合批,其他组合类似
      3).A物体(-1,-2,3),B物体(1,2,3)、(-1,2,-3),偶数个负缩放,其他组合类似
      总结为:对于两个相同的物体,当两个物体三个轴向的负缩放的个数为偶数个时(0个,2个),可以合批,当两个物体中任意一个物体或者两个物体同时三个轴向的负缩放的个数为奇数个时,不合批。此前有很多文章说对于不同缩放的物体,无论是否为负缩放,均不会合批处理,笔者使用的unity版本是unity2019.1.7f1,可能是因为unity在某个版本已经修复了该问题,有知道的朋友,请告知一声,谢谢。
  • 使用不同的Material实例会导致GameObjects不能一起批处理,即使它们基本相同。阴影渲染(shadow caster)是一个例外,下文会解释为什么。

  • 带有光照贴图的GameObjects有额外的渲染器参数:保存光照贴图的索引和偏移/缩放。一般来说,动态光照贴图的GameObjects应指向完全相同的光照贴图位置才能被动态合批处理。

  • 使用多个pass的shader不会被动态合批处理。

    • 几乎所有Unity Shaders在forward rendering(前向渲染)中都支持多个灯光 ,为了他们有效地进行额外的传递。额外的pre-pixel lights的绘制调用不会被动态合批处理,这个在移动平台上比较少遇到。
    • The Legacy Deferred (light pre-pass) rendering path 中禁用动态批处理,因为它必须绘制两次GameObjects。

github 上Unity官方总结了25种不能被合批处理的情况, Unity-Technologies/BatchBreakingCause

动态合批处理的工作是在cpu上将所有GameObject顶点转换到世界空间,因此,如果该工作小于执行绘制调用,则这是一个优势。绘制调用的资源需求取决于多方面的因素,主要是使用的图形API。例如,在 consoles or modern APIs,比如Apple Metal,绘制调用开销通常要低得多,此时动态合批处理就不再是优势了,所以动态合批处理并不是万能的啊。

动态合批处理(Particle Systems, Line Renderers, Trail Renderers)
对于Unity动态生成的几何体的组件,动态合批处理与网格相比有不同的工作方式。

  • 对于每个兼容的渲染器类型,Unity将所有可混合内容构建为1个大型顶点缓冲区(Vertex Buffer)。
  • 渲染器为批处理设置材质的状态。
  • Unity将顶点缓冲区(Vertex Buffer)绑定到图形设备。
  • 对于动态合批处理中的每个渲染器,Unity将偏移更新到顶点缓冲区(Vertex Buffer),然后提交新的绘制调用。

在评估图形设备调用的成本时,渲染组件的最慢部分是材质状态的设置。相比之下,将不同的偏移绘制调用提交到共享顶点缓冲区的速度非常快。

注意:
1.不同材质的阴影会动态合批,只要绘制阴影的 pass是相同的,因为阴影跟其他贴图等数据无关
2.目前,只有 Mesh Renderers, Trail Renderers, Line Renderers, Particle Systems和Sprite Renderers支持合批处理,而skinned Meshes,Cloth和其他类型的渲染组件不支持合批处理。
3.渲染器仅与其他相同类型的渲染器进行合批处理。
4.对于半透明的GameObject,按照从前到后的顺序绘制,Unity首先按这个顺序对GameObjects进行排序,然后尝试对它们进行批处理,但由于必须严格满足顺序,这通常意味着对于半透明的材质更少使用合批处理。
5.手动的合并GameObject是代替合批处理的好办法,比如使用Mesh.CombineMeshes,或者直接在建模时将多个网格合并成单个网格。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268