笔记(Unity) —— UGUI 合批规则

37 阅读2分钟

合批条件

  • 相同Canvas
  • 相同材质,相同shader
  • 相同贴图(同一图集)
  • Depth相同

详解【Depth相同】

  1. 查阅了很多资料, 也问了AI, 几乎都给出了错误答案: UGUI的合批受到Hierarchy面板上的排列顺序影响, 即如果Hierarchy面板上有如下排列的三张图片, 就会打断合批。之前使用NGUI时确实如此, 但使用一段时间UGUI后发现单纯改变Hierarchy层级并不能降低DrawCall, 就做了实验,并作此文记录
错误:
ImageA (Atlas_1) ✅
ImageB (Atlas_2) ❌ → 打断合批
ImageC (Atlas_1) ✅ → 新的批次

2. ImageA ImageC来自同一图集, ImageB未打图集

  • 如下图所示, 只渲染一张图时, Batch数为7

image.png

  • 渲染两张图时, 由于这两张图满足合批条件, 所以Batch数还是7

image.png

  • 但是: 渲染ImageB之后, 并没有打断ImageA和ImageB的合批, Batch数只上涨了1; 所以可见,Hierarchy面板上的简单顺序并不能影响Batch的合批(打开FrameDebug看一下更明显)

image.png

  • 如下情况才会打断合批

image.png

  1. 总结: 在其他条件满足的情况下, 图片的Detph才是影响UGUI合批的最根本的原因, 跟Hierarchy面板顺序无关!!!那么, 何为Depth, 我自己的粗浅理解如下
  • 把Canvas想象成一张白纸, 放UI即是在上面画东西, 假设Canvas的Depth为-1
  • 如果直接将UI放在Canvas的白纸上, 那么Depth就为0
  • 如果把一个UI放在一个Depth为N的UI上, 那么该UI的Depth就为 N + 1
  1. 用上面的知识来解释上面最后一张图:
  • IamgeB 和 ImageC的Depth为0
  • ImageA的Depth为1, 因为它放在ImageB上
  • 所以ImageA和ImageC虽然满足条件(且Hierarchy面板顺序并没有被打断), 但是两张图片的合批还是被打断了
  1. 注意事项: 一个UI放在另一个UI上,是指物理意义上的重叠(并不是指RectTransform的大小来的), 即如果重叠部分是透明的, 则不算。 如下图, IamgeA从Rect的角度上来说, 确实压在了ImageB上面, 但是压住的部分是透明的, 所以不算, ImageA的Depth还是0, 可以和ImageC合批

image.png

image.png

其他

  • CPU渲染阶段的瓶颈并不仅仅在Draw Call, 也在数据准备阶段(Set Pall Call)

    • Draw Call: 指的是每一次从CPU向GPU下发的渲染指令,即告诉GPU“现在绘制哪些顶点、用哪个材质”
    • Set Pass Call: 指每一次材质或Shader的切换(准确说是Shader Pass的切换) 。每当渲染管线切到另一个不同的 Shader 的 Pass 时,都会发起一次 SetPass