stonstad 发表于 2022-8-7 16:23

UE5动画如何进行调试和优化——动画预算分配器的使用?

动画预算分配器(或动画预算器)系统通过动态限制骨架网格体组件的滴答声来限制运行动画数据的时间。目的是使用固定的 CPU 预算(不超过它),同时以最小的系统开销最大限度地提高感知动画质量。
系统确定每个平台的固定预算(在游戏线程上执行的工作的毫秒数 (ms)),并确定它是否可以完成所有需要的工作,或者是否需要减少工作量完毕。如果需要减少它,它会根据重要性这样做,并针对几个区域,目标是动态调整负载以适应固定(游戏线程)预算。其中的领域包括:

[*]停止打勾并使用Master Pose Component。
[*]以较低的速率执行更新。
[*]在更新之间插入(或不插入)。
启用动画预算器

要使用动画预算分配器,您需要首先从插件菜单中启用它。

[*]从“编辑”>“插件”选项打开“ 插件”菜单 。


2、在 Programming下,启用 Animation Budget Allocator插件并重新启动编辑器。


使用动画预算器

要使用 Anim Budgeter,请通过按 `(反引号键)输入以下控制台命令:

[*]启用 - “a.Budget.Enabled 1”
[*]禁用 - “a.Budget.Enabled 0”
启用插件时,Anim Budgeter 会自动启用。
您还可以使用启用动画预算蓝图节点通过蓝图启用/禁用动画预算器。


目前,这是系统向蓝图公开的唯一方面,系统的其余部分基于 CVars 和 C++ API 调用。
要启用调试显示:
启用调试信息显示的功能目前仅在 GitHub 的主分支中可用。此功能将在 4.23 中得到更广泛的使用。

[*]启用调试显示 - “a.Budget.Debug.Enabled 1”
[*]禁用调试显示 - “a.Budget.Debug.Enabled 0”
启用后,运行时将在视口内显示图表。


该图由以下内容组成:

[*]以毫秒为单位的时间在大约 20 帧的内核上平滑(使其更容易阅读趋势,并且是每个滴答所花费的时间)。
[*]总时间
[*]动画预算(虚线)
[*]性能(实线)
性能将根据需要完成的工作量而有所不同。下面,虚线是我们的动画预算,实线是我们的表现。我们目前的预算不足,因为只有一个角色(玩家)在滴答作响。


下面,我们将字符数增加到 10 个,性能峰值(嘈杂的线条)可以看出性能受到的影响。性能有两条线,灰线是实际的系统性能,有点吵,会根据系统的负载而波动。平滑的白线让您更好地了解实际系统性能。


在下面的最后一个示例中,我们将字符数增加到刚刚超过 100 个,您可以看到性能徘徊在分配的预算(虚线)附近。


这仅适用于动画,表示动画被勾选的频率。
Anim Budgeter 尝试将系统正在执行的工作总量保持在预算范围内,并尝试最大限度地提高系统可以产生的质量。它将尝试以最高帧速率运行最接近、最重要的网格,并将不太重要的事物或距离较远的事物的帧速率推低。这一切都是在用需要完成的工作总量填写预算的同时完成的。
在每个骨架网格体上,您都会看到调试数据:


数字显示更新网格的速率。值为 1 意味着它正在更新并在每一帧都打勾。值为 5 意味着每五帧,它将执行一次更新和滴答。
例如,在Fortnite中,角色由多个骨架网格体(头部、身体、背包等)组成,所有这些骨架网格体都可以在给定时间滴答作响。当我们运行 Anim Budgeter 时,您会注意到除了由数值表示的网格更新频率之外,还使用了文本Lo、Hi或I。这表示网格的标记方式。

[*]嗨 (或高细节) - 意味着骨架网格体组件和运行更昂贵的逻辑。
[*]Lo(或低细节) - 意味着昂贵的逻辑(例如额外的字符部分或更昂贵的可以在远处跳过的工作)没有运行。
[*]I(或插值)- 表示骨架网格体在帧之间进行插值。
下面的示例说明了 Anim Budgeter 更新和优先级如何根据所需的动画工作量进行转换。




动画预算器 C++ API

您可以在以下引擎安装文件夹中访问 Anim Budgeter 的 C++ 文件:

[*]Engine\Plugins\Runtime\AnimationBudgetAllocator\Source\AnimationBudgetAllocator\Public\
下面是IAnimationBudgetAllocator.h:
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
class USkeletalMeshComponentBudgeted;
class UWorld;
struct FAnimationBudgetAllocatorParameters;
/**
* Dynamically manages skeletal mesh component tick rates to try to maintain a specified budget.
*/
class IAnimationBudgetAllocator
{
public:
    /** Get the budgeter for the specified world */
    static ANIMATIONBUDGETALLOCATOR_API IAnimationBudgetAllocator* Get(UWorld* InWorld);
    /**
   * Register a component with the budgeter system. If the component is already registered this function does nothing.
   * Once this is called:
   * - Default tick function will be disabled
   * - URO will be disabled
   * - Parallel anim tasks will be re-routed to the budgeter
   */
    virtual void RegisterComponent(USkeletalMeshComponentBudgeted* InComponent) = 0;
    /**
   * Unregister a component from the budgeter system. If the component is not registered this function does nothing.
   * Once this is called:
   * - Default tick function will be re-enabled
   * - URO will be re-enabled
   * - Parallel anim tasks will be re-routed back to internal functions
   */
    virtual void UnregisterComponent(USkeletalMeshComponentBudgeted* InComponent) = 0;
    /**
   * Update the prerequisites of this component. Should be called when prerequisites may have changed externally.
   */
    virtual void UpdateComponentTickPrerequsites(USkeletalMeshComponentBudgeted* InComponent) = 0;
    /**
   * Set the significance and other flags for the specified component.
   * This information is used to dynamically control the tick rate of the component.
   */
    virtual void SetComponentSignificance(USkeletalMeshComponentBudgeted* Component, float Significance, bool bNeverSkip = false, bool bTickEvenIfNotRendered = false, bool bAllowReducedWork = true, bool bForceInterpolate = false) = 0;
    /** Set the specified component to tick or not. If the budgeter is disabled then this calls Component->SetComponentTickEnabled(bShouldTick). */
    virtual void SetComponentTickEnabled(USkeletalMeshComponentBudgeted* Component, bool bShouldTick) = 0;
    /** Get whether the specified component is set to tick or not */
    virtual bool IsComponentTickEnabled(USkeletalMeshComponentBudgeted* Component) const = 0;
    /** Inform that we reduced work for a component */
    virtual void SetIsRunningReducedWork(USkeletalMeshComponentBudgeted* Component, bool bInReducedWork) = 0;
    /** Set the tick time */
    virtual void SetGameThreadLastTickTimeMs(int32 InManagerHandle, float InGameThreadLastTickTimeMs) = 0;
    /** Set the completion task time */
    virtual void SetGameThreadLastCompletionTimeMs(int32 InManagerHandle, float InGameThreadLastCompletionTimeMs) = 0;
    /** Tick the system per-frame */
    virtual void Update(float DeltaSeconds) = 0;
    /** Set whether this budget allocator is enabled */
    virtual void SetEnabled(bool bInEnabled) = 0;
    /** Get whether this budget allocator is enabled */
    virtual bool GetEnabled() const = 0;
    /** Set the various parameters */
    virtual void SetParameters(const FAnimationBudgetAllocatorParameters& InParameters) = 0;
};其他控制台命令

以下控制台命令也可用于调试 Anim Budgeter:












重要提示:

Unreal软件电脑配置的要求是比较高,特别是实时渲染,前期的硬件成本是比较高的,目前有云端解决方案,使用呆猫云桌面,即使本地普通的电脑也能运行Unreal软件,且普通电脑也能享受行业最高端的CPU和GPU,极大提高制作效率和使用体验,且使用方便快捷,全面支持3D应用软件插件运行,随时调用百余款软件插件,高效作业。
呆猫云桌面可以为UNREAL 用户提供云端制作输出方案,提高工作效率。为Unity用户提供灵活、高效、低成本的云端烘焙服务,享受游戏制作的乐趣。用户在全国各地通过呆猫直接连接服务器,共享一套资产, 可以直接在呆猫上制作 / 修改工程文件,减少数据传输成本。高性能云办公选呆猫!!

Ilingis 发表于 2022-8-7 16:24

不过,连官方文档都用你的,的确是大佬[赞]

zt3ff3n 发表于 2022-8-7 16:26

我用的官方的
页: [1]
查看完整版本: UE5动画如何进行调试和优化——动画预算分配器的使用?