ue4 Slate常用优化指南

授权用户通常会询问如何才能在项目中降低UI渲染成本。当我们为内部项目优化UI时,我们用到了以下经验法则:

  • 消除所有需要每帧运行的内容(tick/绘制),尤其是在蓝图中(tick/绘制)。将蓝图纯粹用于基于事件的逻辑或短暂的动画。

  • 消除绑定属性的使用。属性虽然有用,但考虑到它们会每一帧轮询,其性能并不兼容。消除绑定到蓝图可调用函数的属性尤为重要。

  • 使用无效(invalidation)。无效面板能防止布局每帧都出现在无效面板中所包含的树中的任何内容上。

    4.23版中的无效面板有很多局限性。例如,它们不支持其中的任何控件更新。4.25版对它们做了全面修改。稍后会详细介绍。

两个比较有用的UI优化工具是限位面板(retainer panel)和无效面板,但两者都有一些需要注意的地方。限位器将整个树折叠成单个纹理。它们还支持基于阶段的渲染和有帧率限制的渲染,这意味着每个限位器都可以在单独帧上绘制,避免所有UI布局发生于同一帧上。例如,你可在一帧上绘制小地图,然后在另一帧上绘制血条。你还可以降低限位器的渲染频率,比如以30帧/秒的速度来渲染小地图,而不是60帧/秒。利用基于阶段的渲染,它们可以通过限制同一帧上的重绘次数来减少绘制调用。而缺点是,重新渲染时的开销很大,所以一定要注意。同时,由于它们有各自的渲染目标,因此内存耗用会更多。此外,它们也遇到了4.25版之前的无效面板所遭遇的问题。我们在移动硬件上使用它们,但是我们还是更喜欢先用无效面板。

无效面板的缺点(4.23版中)是当一个控件失效时,无效面板中的整个树都将重新布局和渲染。

两者共有的缺点是都无法处理属性。任何具有绑定属性的核心控件都被标记为易变,这意味着它将重新绘制每一帧。对标记和定时器也不起作用。如果控件在此类面板中,它们基本上不会标记或运行定时器。

扫描二维码关注公众号,回复: 12436219 查看本文章

4.25或以上版本中已移除了LayoutCaching。它已被全局无效取代,全局无效是通过“Slate.EnableGlobalInvalidation”启用的。全局无效可以消除Slate在整个UI中每帧执行时产生的布局和绘制开销。它还解放了手动到处放置无效面板的需求。由于无效面板有一些开销,因此要获得正确的粒度(granularity)可能有些困难。启用全局无效后,如果控件失效,它会被放到黑名单(dirty list)中。下一帧,我们评估该控件如何更改,并决定需要执行哪个层级的树形布局。例如,更改某个图像笔刷的颜色时,只需要重绘该控件。但更改大小时,需要对父项执行无效,因为父项大小会受其子项影响。所有这些操作都是自动执行的,从而产生一组数量最小的需要无效的控件。它还支持注册标记和定时器。

全局无效是Slate的一项非常激进的改变,旨在一劳永逸地解决Slate一直存在的布局开销。我们仍在寻找它的漏洞,但到4.25版时它已经相当稳定了。默认情况下我们不打开它,因为所有项目中经常会出现这种情况:控件在tick或绘制调用中执行海量的每帧逻辑。启用这些功能可有效防止调用绘制和布局,以免破坏尚未做好准备的项目。在《堡垒之夜》中,我们为HUD打开它只是因为,那是我们唯一的性能关键领域。在我们的HUD中,我们对传入控件的内容也非常严格,甚至编写自定义工具和测试来捕捉标记的控件和属性。同样,我们目前还没有解决属性方面的问题,因此每个具有绑定属性的控件都被标记为易变(volatile)且每帧都绘制。它也不能解决单独控件开销高昂的问题(比如在一次tick或绘制调用中执行大量逻辑的控件)。

4.25版中,限位器和无效面板已变为“迷你”全局无效区域。如果你还未准备好完全启用全局无效,那么可以使用无效面板,该面板已有很大改进,具备了全局无效的所有优势。缺点是,所有不在这些无效面板中的控件都会产生额外的开销。

如果你的HUD大部分是静态的,无效会很有用。我们将迷你地图标记为可变的,因为它需要以高帧率运行。这是唯一一种可以这样运作的控件。在《虚幻争霸》中,由于小地图上有大量数据,我们的小地图放在限位器后面,渲染帧率为30hz。通常,我们的小地图都是高度定制的。小地图中没有控件树,只有单个控件,采用了实例化绘制元素使其尽可能高效。

猜你喜欢

转载自blog.csdn.net/zhangxiaofan666/article/details/113089753