UGUI合批学习

Unity批处理之UGUI批处理

1. 前置知识:

动态批处理

动态批处理由Unity自动处理,但是其限制其实有很多,例如:处理顶点数小于300的模型,Shader只能包含1个Pass,Shader中用到的顶点数据不超过3中(如顶点坐标,顶点法线,顶点切线)。

静态批处理

优点就是减少Draw Call。
缺点有以下几点:
①静态批处理只对运行前场景中的静态物体有效,什么意思?就是你必须先把静态物体放置到场景里面,这些物体才能被进行静态批处理。用代码动态创建的物体,即便这个物体是勾上了静态,也是不能被静态批处理的,仍然会增加一次Draw Call。(当然如果这个物体能被动态批处理除外哈)
②静态批处理的物体不能够移动,即Transform组件无效,刚体组件Rigidbody也无效。
③有动画的模型,就不要设置静态批处理属性了,因为不会降低 Batches 的数值,而且有动画的模型, 即使设置了静态批处理, 也跟没有设置是一样的。
④静态批处理会占用更多内存,因为静态批处理会额外拷贝一份网格到内存。

静态批处理的条件简而言之:
1.存在于场景,不能代码动态创建。
2.不能动,即不能有动画等,且不能被移动(Transform和Rigidbody会失效)。

2. UGUI批处理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uSP8ddXQ-1665738977357)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014143115168.png)]

UGUI控件本质上也是网格,与3D模型不同的地方仅仅3D模型的网格是我们在3D Max或者Maya中建模建出来的,而UGUI控件的网格是控件代码代码里面去自动创建网格的。

逐步骤分析Unity是如何渲染的 准备工具 Frame Debug 位于Window/Analysis/Frame Debugger

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UpPgJDD-1665738977358)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014144119339.png)]

**UGUI.Rendering.RenderOverlays ** 相机的设置为Overlay所以UGUI的绘制在最后。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0CipJ3VO-1665738977358)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014144336191.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vrIoy8GO-1665738977359)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014144345643.png)]

两次DrawMesh将Text和Image绘制出来,即Text和Image是由两次DrawCall绘制出来的。

建议多次使用Profiler多次情况分析

1.Canvas顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L6SFtnA0-1665738977359)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014151140505.png)]

2.绘制顺序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwU5i8tI-1665738977359)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014151228425.png)]

3.效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uwmpnuSU-1665738977359)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014151435423.png)]

4.合批打断原因(贴图不同):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7E8HS9FC-1665738977360)(C:\Users\gy\AppData\Roaming\Typora\typora-user-images\image-20221014151515678.png)]

合批规则:

版权声明:本文为CSDN博主「WangShade」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:原文

UGUI的合批单位为Canvas,合批的操作在子线程。

合批步骤

  • 找出所有的Canvas,剔除无需渲染的Canvas(透明度为0、宽高都为0、在RectMask2D空间下且在RectMask2D区域外)

  • 计算Canvas下各UI控件 的深度值Depth(这里的Depth和Image组件中的Depth不是一个东西)

  • Depth计算规则

    1. 按照Hierarchy中从上往下的顺序依次遍历Canvas下所有的UI元素
    2. 对于当前的UI元素
      • UI不渲染 Depth=-1
      • UI渲染,但该UI下面没有其他UI元素与其相交,则Depth = 0
      • UI渲染,在该UI下面有且仅有一个UI与之相交,并且当前UI可以与LowerUI可以合批(材质和贴图相同),则CurrentUI.Depth = LowerUI.Depth;若不能合批,CurrentUI.Depth = LowUI.Depth + 1
      • 如果CurrentUI要渲染,下面有n个元素与其相交,则按照步骤iii,分别计算出n个Depth(Depth_1、Depth_2、Depth_3…),然后CurrentUI.Depth取其最大值,即CurrentUI.Depth = max(Depth_1, Depth_2, Depth_3,…)
      • 这里的下和上指的是Game显示层的高低,就是物理层面的 这个图在这个字体的上面还是下面 。
      • 两个UI元素相交,是指这两个元素的网格有相交(有重叠部分),一定要注意不是两个元素的Rect区域相交
  • 各个UI的Depth计算完毕后,依次按照Depth、material ID、texture ID、RendererOrder(即UI层级队列顺序,即Hierarchy面板上的顺序)排序(条件的优先级依次递减,且均为从小到大排序)。然后剔除Depth = -1的UI元素,得到Batch前的UI 元素队列,这个队列被称之为VisiableList。

    1. 先按Depth从小到大的顺序排序
    2. Depth排完之后,Depth相同的元素再按material ID从小到大排序
    3. material ID排完之后,material ID相同的元素再按texture ID从小到大排序
    4. textrure ID排完之后,textrure ID相同的元素最后再按在Hierarchy上的顺序排序(Hierarchy越上面的越在队列前面)
  • 得到VisiableList之后,判断VisiableList中相邻的元素是否能够合批(相同的材质和贴图)。需要注意这里不再考虑Depth是否相同,只要两个元素相邻然后材质和贴图相同,即使两个元素的Depth不相同,这两个元素也能合批。然后一个批次一个批次的合并网格,提交GPU进行渲染。

合批失败原因:

  1. Additional Vertex Streams — 对象使用MeshRenderer.additionalVertexStreams设定了额外的顶点信息流。
  2. Deferred Objects on Different Lighting Layers — 该物件位于另一不同的光照层中。
  3. Deferred Objects Split by Shadow Distance — 两个物体中有一个在阴影距离范围内而另一个不是。
  4. Different Combined Meshes — 该对象属于另一个已合并的静态网格。
  5. Different Custom Properties — 该对象设定了不同的MaterialProperyBlock。
  6. Different Lights — 该物件受不同的前向光照(Forward Light)影响
  7. Different Materials — 该对象使用不同的材质。
  8. Different Reflection Probes — 该对象受不同的反射探头(Reflection Probe)影响。
  9. Different Shadow Caster Hash — 该对象使用其他的阴影投射着色器,或是设定了不同的着色器参数/关键词,而这些参数/关键词会影响阴影投射Pass的输出。
  10. Different Shadow Receiving Settings — 该对象设定了不同的“Receive Shadows”参数,或是一些对象在阴影距离内,而另一些在距离之外。
  11. Different Static Batching Flags — 该对象使用不同的静态批处理设定。
  12. Dynamic Batching Disabled to Avoid Z-Fighting — Player Settings中关闭了动态批处理,或在当前环境中为避免深度冲突而被临时关闭。
  13. Instancing Different Geometries — 使用GPU Instancing渲染不同的网格或子网格。
  14. Lightmapped Objects — 对象使用了不同的光照贴图,或在相同的光照贴图中有不同的光照贴图UV转换关系。
  15. Lightprobe Affected Objects — 对象受其他光照探头(Light Probe)影响。
  16. Mixed Sided Mode Shadow Casters — 对象的“Cast Shadows”设定不同。
  17. Multipass — 对象使用了带多个Pass的着色器。
  18. Multiple Forward Lights — 该物件受多个前向光渲染影响。
  19. Non-instanceable Property Set — 为instanced着色器设定来non-instanced属性。
  20. Odd Negative Scaling — 该对象的缩放为很奇怪的负值,例如(1,-1,1)。
  21. Shader Disables Batching — 着色器使用“DisableBatching”标签显式关闭了批处理。
  22. Too Many Indices in Dynamic Batch — 动态批处理索引过多(超过32k)。
  23. Too Many Indices in Static Batch — 静态批处理中的组合网格索引过多。对于OpenGL ES来说是48k,OSX是32k,其他平台是64k。
  24. Too Many Vertex Attributes for Dynamic Batching — 欲进行动态批处理的子网格拥有超过900个顶点属性。
  25. Too Many Vertices for Dynamic Batching — 欲进行动态批处理的子网格顶点数量超过300个。

猜你喜欢

转载自blog.csdn.net/weixin_43381316/article/details/127324437