本文主要是介绍UGUI合批学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Unity批处理之UGUI批处理
1. 前置知识:
动态批处理
动态批处理由Unity自动处理,但是其限制其实有很多,例如:处理顶点数小于300的模型,Shader只能包含1个Pass,Shader中用到的顶点数据不超过3中(如顶点坐标,顶点法线,顶点切线)。
静态批处理
优点就是减少Draw Call。
缺点有以下几点:
①静态批处理只对运行前场景中的静态物体有效,什么意思?就是你必须先把静态物体放置到场景里面,这些物体才能被进行静态批处理。用代码动态创建的物体,即便这个物体是勾上了静态,也是不能被静态批处理的,仍然会增加一次Draw Call。(当然如果这个物体能被动态批处理除外哈)
②静态批处理的物体不能够移动,即Transform组件无效,刚体组件Rigidbody也无效。
③有动画的模型,就不要设置静态批处理属性了,因为不会降低 Batches 的数值,而且有动画的模型, 即使设置了静态批处理, 也跟没有设置是一样的。
④静态批处理会占用更多内存,因为静态批处理会额外拷贝一份网格到内存。
静态批处理的条件简而言之:
1.存在于场景,不能代码动态创建。
2.不能动,即不能有动画等,且不能被移动(Transform和Rigidbody会失效)。
2. UGUI批处理:
UGUI控件本质上也是网格,与3D模型不同的地方仅仅3D模型的网格是我们在3D Max或者Maya中建模建出来的,而UGUI控件的网格是控件代码代码里面去自动创建网格的。
逐步骤分析Unity是如何渲染的 准备工具 Frame Debug 位于Window/Analysis/Frame Debugger
**UGUI.Rendering.RenderOverlays ** 相机的设置为Overlay所以UGUI的绘制在最后。
两次DrawMesh将Text和Image绘制出来,即Text和Image是由两次DrawCall绘制出来的。
建议多次使用Profiler多次情况分析
1.Canvas顺序
2.绘制顺序
3.效果图:
4.合批打断原因(贴图不同):
合批规则:
版权声明:本文为CSDN博主「WangShade」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:原文
UGUI的合批单位为Canvas,合批的操作在子线程。
合批步骤
-
找出所有的Canvas,剔除无需渲染的Canvas(透明度为0、宽高都为0、在RectMask2D空间下且在RectMask2D区域外)
-
计算Canvas下各UI控件 的深度值Depth(这里的Depth和Image组件中的Depth不是一个东西)
-
Depth计算规则
- 按照Hierarchy中从上往下的顺序依次遍历Canvas下所有的UI元素
- 对于当前的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。
- 先按Depth从小到大的顺序排序
- Depth排完之后,Depth相同的元素再按material ID从小到大排序
- material ID排完之后,material ID相同的元素再按texture ID从小到大排序
- textrure ID排完之后,textrure ID相同的元素最后再按在Hierarchy上的顺序排序(Hierarchy越上面的越在队列前面)
-
得到VisiableList之后,判断VisiableList中相邻的元素是否能够合批(相同的材质和贴图)。需要注意这里不再考虑Depth是否相同,只要两个元素相邻然后材质和贴图相同,即使两个元素的Depth不相同,这两个元素也能合批。然后一个批次一个批次的合并网格,提交GPU进行渲染。
合批失败原因:
- Additional Vertex Streams — 对象使用MeshRenderer.additionalVertexStreams设定了额外的顶点信息流。
- Deferred Objects on Different Lighting Layers — 该物件位于另一不同的光照层中。
- Deferred Objects Split by Shadow Distance — 两个物体中有一个在阴影距离范围内而另一个不是。
- Different Combined Meshes — 该对象属于另一个已合并的静态网格。
- Different Custom Properties — 该对象设定了不同的MaterialProperyBlock。
- Different Lights — 该物件受不同的前向光照(Forward Light)影响
- Different Materials — 该对象使用不同的材质。
- Different Reflection Probes — 该对象受不同的反射探头(Reflection Probe)影响。
- Different Shadow Caster Hash — 该对象使用其他的阴影投射着色器,或是设定了不同的着色器参数/关键词,而这些参数/关键词会影响阴影投射Pass的输出。
- Different Shadow Receiving Settings — 该对象设定了不同的“Receive Shadows”参数,或是一些对象在阴影距离内,而另一些在距离之外。
- Different Static Batching Flags — 该对象使用不同的静态批处理设定。
- Dynamic Batching Disabled to Avoid Z-Fighting — Player Settings中关闭了动态批处理,或在当前环境中为避免深度冲突而被临时关闭。
- Instancing Different Geometries — 使用GPU Instancing渲染不同的网格或子网格。
- Lightmapped Objects — 对象使用了不同的光照贴图,或在相同的光照贴图中有不同的光照贴图UV转换关系。
- Lightprobe Affected Objects — 对象受其他光照探头(Light Probe)影响。
- Mixed Sided Mode Shadow Casters — 对象的“Cast Shadows”设定不同。
- Multipass — 对象使用了带多个Pass的着色器。
- Multiple Forward Lights — 该物件受多个前向光渲染影响。
- Non-instanceable Property Set — 为instanced着色器设定来non-instanced属性。
- Odd Negative Scaling — 该对象的缩放为很奇怪的负值,例如(1,-1,1)。
- Shader Disables Batching — 着色器使用“DisableBatching”标签显式关闭了批处理。
- Too Many Indices in Dynamic Batch — 动态批处理索引过多(超过32k)。
- Too Many Indices in Static Batch — 静态批处理中的组合网格索引过多。对于OpenGL ES来说是48k,OSX是32k,其他平台是64k。
- Too Many Vertex Attributes for Dynamic Batching — 欲进行动态批处理的子网格拥有超过900个顶点属性。
- Too Many Vertices for Dynamic Batching — 欲进行动态批处理的子网格顶点数量超过300个。
这篇关于UGUI合批学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!