Unity UI分析:谁破坏了我的批处理?


您花费了无数的时间来优化Unity UI。 但是为了引起抑制,只需对几乎不可见的UI Canvas元素的微小属性进行少量修改即可。 发生这种情况时,即使对Unity UI进行性能分析也无法避免降低FPS。 您准备好解决长时间的错误吗?

这正是我上一个项目中发生的事情...

我在Oculus Quest的游戏端口中努力优化了几个UI面板。 基本上,任务是将透支水平降低到可接受的值,以便GPU可以应对最重要的事情-真实的3D渲染。

因此,我至少花了一个月的时间对Unity UI进行优化,最终还是取得了不错的进展。

在某个时候,UI变得如此优化,以至于几乎不影响GPU时序。 我实现的不透明UI的调光技术弥补了UI分层(在其他元素上方绘制的元素)引起的大多数重绘。

因此,我得到了一个高度优化的混合UI系统,该系统实质上与在其下绘制的3D元素重叠。 丢弃这些重叠片段的呈现变得非常容易。

但是,这项工作还远远没有完成...

当我插入Unity UI Profiler时 ,一件事引起了我的注意。

我看到过载的CPU在渲染UI的每一帧中花费超过1毫秒 。 对于一个为整个游戏分配13毫秒预算的平台来说,这是很多时间:物理,逻辑,3D渲染,输入,VR和网络代码。

毕竟,在某些情况下,UI甚至会更多地“杀死” CPU性能。


Unity UI:昂贵的构建批处理

这说明一件事: 可以针对GPU优化UI,但这不一定意味着针对CPU进行了优化

实际上,在渲染Unity UI时,CPU和GPU任务非常不同。 毫不奇怪,我建议以不同的方式进行CPU和GPU优化,这在我之前关于Unity UI优化的文章中已有讨论。

对Unity UI的进一步分析揭示了一个明显的问题:在每个新框架(即 画布(Canvas Rebuild)在每个框架中都进行了重建

CPU上的恒定负载为1 ms ...哦,哦。

但是Unity为什么要对我这样做? 我以为Unity会缓存所有的Canvas接口...

其实是的。 Unity有效地缓存了Canvas,因此只能收集一次。

但是,当您更改“画布”中任何UI元素的属性-颜色,位置等时,就会出现问题。

就是说,我们喜欢的所有动画,例如,当您将鼠标悬停在鼠标上时,其效果会降低生产力,而您可能不知道这些。

更改UI属性后,Unity会运行著名的Canvas Rebuild,这会破坏游戏的性能

接口的Canvas Rebuild强制Unity引擎迭代遍历此Canvas的所有UI元素,以生成优化的绘制调用列表(许多顶点,颜色,材质等)。 而Canvas Rebuild所需的时间要比Seat熊猫 从零加速到60 mph所需的时间长。

意识到我们一直在遭受Canvas Rebuild的困扰,因此提出一个问题是合乎逻辑的...

为什么我们会遭受Canvas Rebuilds的困扰,对此该怎么办?

为了回答这个简单的问题,我不得不花费5个多小时来研究该主题并使用Unity UI Profiler

让我们做对。

1.对Unity UI进行性能分析:目前一切正常...


假设我们有一个简单的UI。

该用户界面不执行任何操作,仅出现在屏幕上,使尝试通过它查看内容的玩家感到烦恼。

作为“网格布局”组中的350多个图像的集合,它看起来像这样:


Unity UI分析示例

即使有350多个图像,一切也还是井井有条。 在标准情况下,UI将仅在两个绘制调用中进行渲染,因为其中只有两个唯一的图像不在精灵图集中。

实际上,在分析器中,我可以看到CPU几乎没有负载。 在UI上花费的大部分时间都少于0.01 ms ,这真是太好了。


Unity UI分析:一个神秘的浪潮

(...大部分时间)

等一下,图表末尾的CPU资源激增来自何处?

2. Unity UI分析:突然的画布重建!


Unity Profile结束时发生了什么? 非常奇怪,仅一秒钟,Unity UI上的CPU开销就翻了一番。

我想玩游戏

在以下示例中找到两个区别(您可能必须在单独的窗口中打开图像才能看到更好的图像)


Unity UI分析:低成本画布


Unity UI分析:画布重建

我给你五秒钟的时间来解决。

5,4 ...好吧,这是简化任务的提示:


Unity UI分析:开销画布重建

哇!

PostLateUpdate.UpdateRectTransformUGUI.Rendering.UpdateBatches强烈希望成为该节目的主要明星。

这些区域是做什么的?

第一个是UpdateRectTransform ,它清楚地表明某些对象的变换已更改,因此Unity必须执行昂贵的逻辑以反映视觉变化。 我们不知道它是RectTransform的位置,旋转,比例还是其他某些属性。

地狱,我们甚至都不知道这只是一个属性还是一次。 是单个对象还是多个对象? 哪一个呢? 这就是问题:我们不知道

第二个昂贵的片段UpdateBatches与重建整个Canvas几何体的需求有关。 此过程称为“ 画布重建” 。 重建Canvas意味着Unity遍历整个Canvas层次结构以生成绘图调用列表。 计算所有元素的顶点,索引,颜色和uv,然后执行传递过程以合并最大可能的绘制调用次数,以减少CPU上的不必要负载,并将其传递给图形驱动程序。

现在,我们似乎知道发生了什么,并且步入正轨。 但是如何避免这种Canvas检修? 是什么原因造成的?

我们需要更多具体信息...

总结一下

  • 更改UI元素中的属性会将元素本身标记为脏
  • UI元素可以完全脏,但也可以部分脏:顶部脏,布局脏,材料脏。 从部分脏状态恢复比较容易
  • 将任何Canvas元素标记为脏后,Unity会完全重建它
  • 画布重建对于CPU来说是昂贵的,因此要避免的最重要的事情是

3.寻找有害生物:政治上不正确的暴力手段


我们仍然需要回答以下问题:

是什么原因导致这些画布重建?

事实证明,找不到快速的方法,特别是对于大型的Canvas层次结构。

但是首先,我将向您展示一种蛮力方法,以查找Canvas Rebuild的原因


1.让Unity UI Profiler继续记录

我们将筛选指标,以便我们专注于最重要的:渲染,脚本和UI。

跟踪初始标记以了解当前方案的成本,其中应包括昂贵的Canvas Rebuild。


2.从用户界面停用游戏对象并比较读数

选择游戏对象组并将其停用。

比较性能指标。

如果读数没有太大改善,请继续停用游戏对象,直到看到明显的改善为止。


3.找到什么改变了它的属性

我们能够选择调用“画布重建”的对象。 但是,究竟是什么引起了他们的原因?

也许它的规模会随着脚本而改变? 还是他的位置随着动画而改变?

右键单击RectTransform并选择“ 在场景中查找引用 ”将非常方便。

当您找出导致Canvas重建的原因时,请对其进行一些处理,例如,关闭动画或变换。

Ruben,但是如何在庞大的UI层次结构中使用此方法? 别跟我说废话

我说过这个过程既不会很快也不有趣,但是玩家会感谢您的。

这就是重点。 首先,存在巨大的等级制度不是理想的情况。 如此庞大且深入的层次结构使Canvas Rebuild对CPU而言是如此昂贵。

但是可能会(并且将会)出现大量且嵌套的UI层次结构,因此希望Canvas Rebuild最重要的是游戏性。

尽管蛮力方法有助于找到Canvas大修的根源,但从长远来看,它的伸缩性不好。

在优化UI方面变得更加专业之后,我创建了一个工具,可以提供所需的所有答案,从而使项目满足玩家的期望 ...


分析画布重建

4.奖金:增强Unity Profiler UI优化功能


我希望您已经了解Canvas Rebuild的频繁程度和令人不安的情况。

这些感染我的游戏的剧变夺走了整个CPU预算的10%之多!

如我们所见,有一种蛮力方法可以找到Canvas Rebuild源。 也许您可以使用我的有关优化Unity UI的文章中列出的策略来处理它们。

但是,这种容易出错的过程永远无法满足真正的专家。 您可能需要花几天的时间与Canvas Rebuild进行斗争,但是在最意外的时刻,一旦插入Unity UI Profiler,它们就会消失。

如果您正在开发用于VR的游戏,这将变得至关重要。 我们不希望在世界空间的UI中重建Canvas。 如果您不能摆脱改革,那么您的玩家很可能会忍受不了。

好了,我有了摆脱Canvas Rebuilds的想法。 但是Unity Profiler几乎不提供任何信息! 你有什么建议?

很高兴你问。 事实证明, 我们可以说服Unity Profiler向我们提供有关妨碍UI性能的有用信息

我们可以扩展Unity UI Profiler的功能。 为此,您需要修改公共可用的Unity UI源代码。 到达源代码后,您将需要查找发生Canvas Rebuilds的代码功能 。 然后,我们需要使用BeginSampleEndSample事件 探查器进行 API魔术。

如果您运行的是Unity 2019.1或更早版本,则Unity UI源代码已上传到Bitbucket存储库中 。 还有一个用于下载,安装和修改的指南。

我有什么建议? 使用不低于2019.2.0的更高版本的Unity。 默认情况下,较新版本的Unity带有源UI ,因为UI系统现在是程序包管理器的一部分。 这是最轻松的方式。

这是我在研究期间发现的代码清单,可以在其中添加Profiling API调用:



Unity UI:分析源

有帮助吗? 是的

对艺术家/设计师来说方便吗? 不行

是诗人编写了小型的开源Unity扩展 ,扩展了Unity Profiler的功能


这个免费的工具将使我们能够在不同的配置模式之间快速切换,以确保最佳的游戏性能。

这个Unity Profiler扩展器的最好之处是什么? 它可以在编辑器外部运行,从根本上减轻了在为Android和其他平台配置UI时的麻烦。

在这里,它的所有功能仅由两个按钮控制:

  • Buff我的Unity Profiler
  • Nerf我的Unity Profiler

您可以在此处获得此工具。

Source: https://habr.com/ru/post/zh-CN472854/


All Articles