UE5——动画混合(2)

一、引言

接上文《UE5——动画混合》,UE5还提供了 遮罩混合、惯性化两种混合,下面将讲述这两种动画混合方式

二、UE5上实现

1、遮罩混合

遮罩混合与《UE5——动画混合》中的 “骨骼的分层混合” 的运行逻辑其实是的一样的。相比起 “骨骼的分层混合”“遮罩混合” 的可控性、自定义化程度更高,可以细化到每一块骨骼的混合比重。如下图:

我们创建了一个名为 “装弹” 的混合遮罩,可以看到上半身的混合系数都是1,也就是100%混合,其余的骨骼混合系数为0(图片有限不展示了),表明下半身不进行混合。

ps.这里要注意,遮罩的概念是针对“骨骼”的,一开始在想的时候误入歧途将遮罩的概念误以为是针对“动画”,遮罩的概念应该是:针对该骨骼的所有动画混合的一系列系数的合集,因此不同骨骼之间的遮罩是不能共用的!
请添加图片描述

如下图,我们依旧采用“骨骼的分层混合”节点,将“run”动画和"装弹"动画进行混合,并在混合遮罩处选择我们刚刚创建的 “装弹”遮罩
请添加图片描述

最终我们可以得到和之前一样的效果(可以回过去看上一篇)
请添加图片描述

上述节点遮罩及节点参数最终的翻译即:
将run动画作为基础动画、装弹作为融合动画,进行100%(混合节点上的Blend Weight0 =1.0)混合,我们采用“装弹遮罩”作为混合系数,因此最终只有上半身执行了混合,由于两个系数都是1,即100%,因此最终的效果就是上半身完全采用装弹动作,下半身保持基础动画run动画。

2、混合描述

虽然UE文档里面将 “混合遮罩和混合描述” 放在一起,但实际上他们两个的含义是不一样的,下面分别讲述为什么他们放在一起及他们的区别

1、混合遮罩和混合描述的异同

相同之处:
1、都是对动画混合的一种描述;描述的对象都是针对骨骼
2、他们创建的方式都是一样的,在骨骼编辑器里面(如下图的“添加时间混合描述”、“添加权重混合描述”) 哈哈哈哈哈哈(强行一样!)

不同之处:
混合遮罩是 动画之间混合比例的描述;混合描述是 用于定义每个骨骼的混合速度
因此前者更倾向于对于产生一个新动作,而后者更倾向于对动画之间过渡时的描述
请添加图片描述
混合描述UE5提供了两种,即如上提供的混合描述“添加时间混合描述”、“添加权重混合描述”

2、时间混合描述

时间混合描述(Time Blend Profiles) 在混合时使用归一化的 (0 - 1) 因数乘以基本的混合值。数值 1.0 意味着以正常速度混合,数值越小混合越快。数值 0.0 代表瞬间混合。

还是依旧对上下半身进行区分,采用不同的系数来理解 “时间混合描述”,先采用
上半身:1
下半身:0.5
的系数混合
请添加图片描述

节点采用 “布尔混合姿势”,并在右边选择刚刚创建的描述

请添加图片描述
请添加图片描述

“时间混合描述” 系数使得腿部以两倍的速度进行混合。在 以布尔混合姿势 节点上使用,基本混合时间设为 1.0 秒,那么腿部只需要 0.5秒来完成混合。其余所有设为 1.0 的骨骼仍然需要基础的 1.0 秒。

上面这个能感觉到腿部有些不协调,实际上是因为腿部的混合比上半身快,导致这种效果。

下面分别用另外两组数据做对比
请添加图片描述
上图为:上半身1,下半身0
请添加图片描述
上图为:上半身1,下半身1。此时上下半身的不协调效果消失了。

3、权重混合描述

权重混合描述(Weight Blend Profiles) 在混合时相对基本混合值使用权重因子。数值 1.0 将会以正常速度混合,数值越大,混合速度越快。

这里同样采用 “布尔混合姿势”,上半身系数为1,下半身10,即原速、10倍速混合,可以看到,在动作切换的时候,下半身的跳跃在很短的时间内就进行完了转换!
请添加图片描述
请添加图片描述
请添加图片描述

将上下半身均调整为1,如下图,此时上下半身均是在2s才完成了彻底的混合
请添加图片描述
请添加图片描述

3、惯性化

1、惯性化原理

惯性混合(Inertial blending) 是传统动画淡入淡出的高性能替代方案,可生成后期处理的自然过渡。激活惯性混合后将不再计算源姿势。相反,传统混合在过渡期间会计算源姿势和目标姿势,将其组合成混合姿势。

惯性化 首次提出是在这个GDC上——Inertialization-High-Performance-Animation-Transitions,引用里面的一句话来说 “现实中我们的动作本就不是“混合”出来的,但是这些动作都具有惯性!”,或许这就是他们产生这个算法的起源。关于惯性化的推导过程可以详见《惯性插值-优异的动画过渡算法》,这篇文章将GDC中提到的惯性化原理拆分并且讲解的很细致了,
总结一句话就是:惯性插值的核心算法为: x ( t ) = A t 5 + B t 5 + C t 5 + D t 5 + E t 5 + F x(t)=At^5 + Bt^5 +Ct^5 +Dt^5 +Et^5 +F x(t)=At5+Bt5+Ct5+Dt5+Et5+F
我们要去除公式中的A、B、C、D、E、F并将式子转化为仅含x0(初始值)、v0(初始速度)、t1(惯性化持续的时间即整个过程的时间)、t(当前时间)的关系式

2、惯性化在UE5中的使用

请添加图片描述
请添加图片描述
请添加图片描述
图一为惯性化节点在动画蓝图中的使用,gif1为使用 “标准混合” 后的过渡效果,gif2为使用 “惯性混合” 后的过渡效果,通常 惯性化节点 尽量靠近 输出姿势(Output Pose)节点,这有助于减少或消除图表中的标准混合,并提高性能。
惯性化节点能够处理多个 【惯性混合请求】,因此将 “惯性化节点” 放在最后能够处理之前的所有 【惯性混合请求】,而惯性混合的性能相比标准混合性能来的高,故能提高性能!

在文档中还提到了:若图表包含惯性化请求但是缺少惯性化节点,将在 消息日志(Message Log) 窗口中记录运行时错误。也就是指下面代码

/*static*/ void FAnimNode_Inertialization::LogRequestError(const FAnimationUpdateContext& Context, const FPoseLinkBase& RequesterPoseLink)
{
    
    
#if WITH_EDITORONLY_DATA	
	UAnimBlueprint* AnimBlueprint = Context.AnimInstanceProxy->GetAnimBlueprint();
	UAnimBlueprintGeneratedClass* AnimClass = AnimBlueprint ? AnimBlueprint->GetAnimBlueprintGeneratedClass() : nullptr;
	const UObject* RequesterNode = AnimClass ? AnimClass->GetVisualNodeFromNodePropertyIndex(RequesterPoseLink.SourceLinkID) : nullptr;

	FText Message = FText::Format(LOCTEXT("InertializationRequestError", "No Inertialization node found for request from '{0}'. Add an Inertialization node after this request."),
		FText::FromString(GetPathNameSafe(RequesterNode)));
	Context.LogMessage(EMessageSeverity::Error, Message);
#endif
}

通过两幅gif可以看出 “惯性混合” 的效果不如 “标准混合”,原因中文档也有描述:由于惯性混合是 后期处理 ,用于将动作过渡到目标动画,因此短混合效果最佳。
请添加图片描述

3、【惯性混合请求】的来源

“惯性混合请求” 来源主要有三个地方

1、混合节点的请求
请添加图片描述

2、状态机过渡的请求

请添加图片描述

3、链接动画图表和分层动画图表的请求
请添加图片描述

ps:链接动画图表和分层动画图表其本质就是一张新的动画蓝图!,关于惯性化在UE5中的实现代码在如下位置
在这里插入图片描述

补充上一篇

《UE5——动画混合》 中出现的不同颜色的骨骼,其实可以在下面面板中设置(后面在文档中看到的)动画节点参考
请添加图片描述

引用

【UE5】混合节点文档
【UE5】混合遮罩和混合描述文档
【UE5】动画层文档
【UE5】动画蓝图链接文档
惯性插值算法解析

猜你喜欢

转载自blog.csdn.net/weixin_40301728/article/details/128139562