UGUI的渲染
参考文献:
https://docs.unity3d.com/Packages/[email protected]/manual/index.html
https://zhuanlan.zhihu.com/p/343524911
UGUI渲染的层级
UGUI是基于GameObject的 表现在于Hierarchy窗口的层级顺序会影响到渲染
从上到下 排的越高就越先渲染
对于同一画布下的元素 siblingIndex越大 渲染便越靠前
也就是说在同一父物体下 较低层级的物体渲染便越靠前
而对于不同画布来说决定因素有很多
同一Sort Order下的模式为Overlay的画布 它们之间的渲染层级也是基于场景层级
siblingIndex越大 渲染就越靠前
如果不同SortOrder下模式为Overlay的画布 SortOrder越高那就渲染的越靠前
Overlay模式下画布相对于场景中的3D物体 总是渲染在最前面的(HUD)
如果是Camera模式下 那么3D坐标就会影响到渲染了 会受到3D物体的遮挡(在3D场景里显示2D界面)
而WorldSpace模式下 3D坐标仍然会影响到渲染 但是不会受到3D物体的遮挡(例如血条UI)
UGUI是如何渲染一张图片(UI元素)的?
当你创建了一张图片(UI元素) 会向画布层注册一次渲染的事件
这样做的好处在于 一帧内发生多次数据变化 并不会执行多次的渲染更新
而是画布每一帧都去运行一次渲染的事件 批量更新元素 也就是说降低了渲染更新的频率
所有的显示用的UI元素(图片、文字)有共同的基类Graphic
画布在渲染的时候会对所有的Graphic进行合批
这就导致了UGUI重绘的时候开销比较大 一个元素的更改会引起同一画布下的其他元素也被触发重新渲染
这里就会引进我们的第一个优化相关的概念
Rebatch
指的是Canvas分析UI节点生成最优批次的过程
这一类对UI元素Mesh的操作是发生在C++层的
每个Canvas独立处理 互不影响
在unity5.2之后改用多线程 大大减少了主线程的压力
但是该做的优化还是要做的
UGUI的布局渲染
UGUI提供了很多自动布局的组件 例如Horizontal Layout/Vertical Layout/Grid Layout
但是使用这些组件方便的同时也是有代价的 这些自动布局实现自适应需要多次计算
大致可以分为下面几个过程
布局计算->计算后更新布局->对于嵌套的布局递归计算
在游戏运行过程中布局下的元素数量发生动态改变时也会触发计算
这里会引入第二个优化相关的概念
ReBuild
指对material和layout的操作
例如Layout组件调整RectTransform尺寸
Graphic组件更新材质 Mask执行Cull等
在出现的数量多了的情况下也要考虑对这些进行优化
Mask和RectMask2D对渲染造成的影响
RectMask2D相对比较友好 不会额外增加Drawcall 但是只能遮挡矩形区域
Mask相对性能负担较重 会打乱合批的过程 但是没有形状限制
圆形的Mask边缘锯齿比较明显 而且遮挡效果是显示上的 射线层不会因此变化
URP对UGUI的影响?
基本上没啥太大影响
URP的Camera和之前的不太一样 可能需要调整一下相机的RenderType
例如你想要一个单独的UI相机 它的相机渲染模式必须是Overlay的
然后添加进主相机的Stack里就正常了