游戏引擎之高级动画技术

一、动画混合

当我们拥有各类动画素材(clips)时,要将它们融合起来成为一套完整的动画。
最经典的例子就是从走的动画自然的过渡到跑的动画。
在这里插入图片描述

1.1 线性插值

不同于上节课的LERP(同一个clip内不同pose之间),动画融合需要的线性插值是不同clip之间的插值。
以走-跑为例,可以用速度来判断两个clip的权重然后来插值。
在这里插入图片描述

1.2 Align Blend Timeline

虽然线性插值本身简单,但其实现的一个重要前提是能够找到两个clip中匹配的对应pose(帧)去做插值,因而我们需要艺术家在做DCC(Digital Content Creator)时确保两个clip的节奏相同,这样可以在归一化后保证每一帧都对应一样的动作(比如取时间t时走的pose是踏在地上,跑也是一样,只是动作有所不同)。从而方便后续插值,这也是因为动画是不断循环所致,不然这帧吻合,下一帧因为两个clip节奏不同就不行了。
如下图就是跑是走的速度的两倍时如何根据当前速度进行插值时时间线上的变化(其中length是指时间长短),delta time是指要去对应clip1和clip2的哪一个时间帧去取对应的pose。
在这里插入图片描述

二、 混合空间 Blend Space

事实上当我们去插值动画的时候,并不局限于在两个clip中插值,也可以在多个动画clip中插值(比如直走、向左走以及向右走),而且它们之间权重的设置也未必一定要均匀或线性插值,而blend space就是用来指导采样权重的东西。(在此处是一维Blend Space)

在这里插入图片描述
进一步,如果我们除了角度以外,还可以同时变速度,那么就需要一个二维的Blend Space如下图:
在这里插入图片描述
由于实际需求上各个clip不一样(比如艺术家认为向左向右走时速度超过一个很低的阈值就直接进入跑的clip),那么此时就无法像上图一样均匀插值,不同的clip在整个采样空间上的分布是不均匀的,如下图:
在这里插入图片描述
此时如果对每一帧插值都要对所有clip去插值,则cost太高了,所以实际处理中会利用德劳内三角化将这些clip化成不同三角形,然后根据当前的速度和方位确定当前的点在哪里,哪个三角形内。最后用重心插值对三角形的三个点(三个clip)进行插值。

2.1 Skeleton Masked Blending

当我们想融合某个动画且这个动画只对角色的局部起到影响时,就可以使用一个blend mask去遮住无关的部分,只对需要的部分进行blend。比如角色的鼓掌动画只对上半身产生影响,所以我们可以在blend mask中将下半身的骨骼设为0(遮住),从而实现在各种状态下(站立、蹲下、做下、行走等)的鼓掌动作。
在这里插入图片描述

2.2 Addictive Blending

当我们在以上基础上想再加一个点头的动画,那么可以使用addictive blending。这个技术提出一个概念:difference clip。不同于常规的完整的一个动画clip,它是作为差值存在,即加在其他clip上从而产生进一步效果的一种clip。具体可能表现为一个旋转或一个scale变化等。
addictive blending一般使用和制作的比较谨慎,因为容易带来问题,比如本身转头这个addictive blending没什么问题,但是如果肩膀已经转的基础上头仍可以转原来的极限角度,则会导致超过头实际能扭的角度,从而看起来很不自然。

三、动作状态机 Animation/Action State Machine(ASM)

当我们在进行动画设计和融合的时候,会发现有些动画clip是存在逻辑关系的而不是可以任意插值的,比如“跳”这个动作我们一般分为“起跳”、“滞空loop”以及"落地"三个部分,而且其存在明确的顺序关系。因而ASM就被引入了进来。
ASM包含“节点node”和“变换transitions”。
在这里插入图片描述

3.1 节点Node

节点分为两类:clip和blend space。前者可以不止是指一个动画clip,也可以把一整个blend space打包成一个节点,甚至可以把一个动画蓝图放进去当一个节点;当角色发生转变时进入另一个节点,而且这种转变是会自动发生,举个例子:当人物进行跳这个动作时,相关的这个ASM就会被调用进入起跳状态,然后根据具体的判断标准,角色会自动从一个状态节点切换到下一个状态节点,直到全部完成之后跳回到角色本身。
在这里插入图片描述

3.2 变换Transitions

转变本身是一个过程(函数),最简单就是表明从一个节点到另一个节点,当然也可能涉及到两个节点之间blending的问题,即两者切换时不是突变,而是有一个时间间隔完成插值过渡,此时经常会用到经典的0.2秒。
另外,transitions的核心问题在于触发条件,比如跳到什么程度会从“起跳”节点进入“滞空loop”节点。事实上,transitions的触发条件可能有多种。

3.3 Cross Fades

当进行transition的时候如果要进行插值,会有两种常见的方式:

常规的smooth transition。即像上述所讲的一样在符合可以同步前提下进行两个动画clip下的blending。
Frozen transition。在上一个动作完成过程中将一个动作blending进来,表现为上一个动作做到一半(即做到第二个动作即将进来的瞬间状态)时加入第二个动作。
在从“跑步”到“起跳”为例的transition中,前者会产生跳起来后仍有部分跑步的样子(形式原地跳但同时在跨步),而后者则会产生从跑着停滞下来跳起来的感觉。
在这里插入图片描述
具体使用哪一种融合方法主要由艺术家决定。

事实上,cross fades的方式远不止线性变换一种,如下图所示有超多方法:
在这里插入图片描述
但一般来说实践中基本上只用到左边所述的两种:线性和“easy in easy out”。后者一般是用cubic-bazier曲线来表示,来实现一种“平滑-陡峭-平滑”的融合过程(感觉就是让融合发生的核心部分在很短时间内完成)

另外,像上面提到的,ASM的节点可以远不止一个动画,而transition的具体设置也可以自定义,比如下面就是unreal的一个展示:
在这里插入图片描述

3.4 Layered ASM

多层次的动画状态机,玩家的不同部分有不同的动画状态机,比如玩家在攻击敌人的时候,上半身播放对应的技能,下半身则根据玩家的操作改变对应的状态。
在这里插入图片描述

四、 动画混合树

而随着技术的发展,现在普遍使用的是动画混合树。
在这里插入图片描述
其中每个非叶节点的产出都是一个pose。
比较常用的操作有lerp(包括多个输入的lerp,此时它们的权重另外输入)、相加(addictive blend node)等。
因而不难发现,上述layered ASM本身也是动画树的一种情况。
在这里插入图片描述

动画树的一个特点是递归:
因为动画树中叶节点可以是单个动画clip、blend space和ASM三种内容,所以导致其叶节点本身也可以是一个内含很多node的小动画树。

另外,动画树的核心作用是控制变量,动画树会定义大量变量暴露给外面的game play系统来进行控制,而这些变量的值决定了动画的混合行为。
通过这个设计,我们只需设置这些变量的值就可以决定动画实现。
变量有两种,一种是环境变量,比如有一个变量是角色当前血量,如果设定到了50%以下就切换成虚弱的动画。
还有一类变量类似于类的private data,通过event触发去进行调整。event概念引用于UE,即事件。当某件事发生的时候,会改变动画树中的某些变量,从而影响动画混合效果。

在这里插入图片描述

五、IK技术 (Inverse Kinematics)

先了解一些基础概念:
在这里插入图片描述
简单来说,根据动画移动到某个位置属于FK,要根据要到的位置设计动画属于IK。而end-effector就是一个让角色移动到某个位置的效果器。
IK问题的经典例子是在不平的路上走路,或者用手抓某个物体等。

5.1 Two Bones IK

最基础的IK方法,如下图:
在这里插入图片描述

这个公式是余弦定理的应用,如果想看证明的话请移步正弦定理和余弦定理的文章

两根骨骼(大腿小腿)形成了一个三角形,如果确定了最后要踩在哪个位置,则可以算出c的大小,从而利用余弦公式算出大腿需要抬起来的角度θ。
这样做会存在一个问题,就是不确定这个三角形会在哪个平面(膝盖可能内翻也可能外翻),这是因为大腿和小腿本身的旋转就不只是局限于前后平面。
在这里插入图片描述

解决方案是让艺术家提供一个reference vector,再加上大腿根到脚的连线,从而可以确定一个平面,而这个平面和大腿旋转的球以及小腿旋转的球结合起来可以把膝盖的位置缩小到两个点,再利用向量点积的正负结果判断膝盖应该是弯向前而不是逆向的。
(另一种或许更容易理解的解释和是:本身大小腿的两个球形空间相交与一个圆,而reference vector和大腿根到脚连线形成的平面与这个圆又相交,从而形成两个点)。
在这里插入图片描述

5.2 Multi-Joint IK

事实上,大部分IK问题都没有Two Bones IK那么简单。当涉及到多个Joint的时候,IK问题存在两个难点:

  • 多维的非线性的问题很难在实时中计算
  • 很多情况下会存在非唯一解
    在这里插入图片描述

此时首先要做的第一步是判断可达性,即先判断角色能不能到达目标位置。而不能达到分两种情况:

  • 全身所有骨骼加起来都没法碰到目标位置
  • 全身所有其他骨骼加起来的总和与最长的骨骼比起来的差大于目标位置的位置。

具体如下图:
在这里插入图片描述
除了可达性判断外,另外很重要的一点是骨骼的旋转是受限的,尤其是人体,不同骨骼的旋转模式不一样。错误的处理会导致很离谱的扭曲。
在这里插入图片描述
那么具体怎么处理呢?
由于直接针对高维算式去解存在成本高以及不一定完全正确的问题,所以在工程中开发出了一些实际好用的方法如下:
在这里插入图片描述
其具体逻辑如principle所述。
针对CCD,后续又提出了一些优化,比如:

  • 限制每次旋转的角度( tolerance regions),从而让整个旋转尽量均摊到每个joint上。
  • 让越靠近根节点的joint旋转角度越小等

另一种方法是FARBRIK(Forward And Backward Reaching Inverse Kinematics),其原理如下:
首先,forward:从最后一个joint开始,把它强行拉到目标位置,然后因此会导致它的骨骼移动,与上一个joint的连接出现偏差,于是就更新目标节点为它移动后的骨骼末尾,并拉动上一个joint到目标节点,不断迭代直至移动了根节点;
其次,backword:反向进行forward的步骤,先拉根节点,最后拉末尾节点

多次来回forward和backward之后,末尾节点就会很接近目标位置了。
与CCD一样,FABRIKF也有带限制版本的:
在这里插入图片描述
同样,它们也都有同一个问题,就是需要迭代很多次。

5.3 IK with Multiple End-Effectors

当控制点有很多时又会遇到不同问题(比如攀岩,同时需要设定的目标点不止一个)
因为当试图把一个点移到它的目标点时可能会让其他已经到位的节点又偏移开。
解决方法是:Jacobian Matrix(优化问题),在后续物理系统会详细介绍
在这里插入图片描述
还有一些其他解决方法(了解):
在这里插入图片描述
而且,IK也还存在很多问题,如下:
在这里插入图片描述
其中第一个是指IK是假设骨骼本身没体积的,但实际上是有的,尤其在蒙皮之后,所以会出现IK后骨骼自我穿插等问题。

完整动画Pipeline:
在这里插入图片描述

六、面部动画

一种面部表情称为一个action unit。一般归结人类表情有28种。
当我们进行表情融合的时候会有一个常见的问题,如下图:
在这里插入图片描述
所以不同于其他动画blending,一般业内使用Morph Target Animation。简单讲就是blending总是以additive的形式去融合,比如直接在眼睛的位置上加上闭着的眼睛,而不会将睁着的眼睛和闭着的去做插值。
MF的问题是存储量大,并且随着表面细节增多计算量也会变很大

针对二维动画,UV Texture Facial Animation也经常使用,它是将不同的纹理贴图来代表不同的表情
在这里插入图片描述

另外,Muscle Model Animation也在发展中(主要在影视行业),它是直接基于物理去驱动面部的43块肌肉来实现各种表情。
在这里插入图片描述

七、 动画重定向 Animation Retargeting

核心意思是将采集到的一套动画能够应用到不同角色上。
以将一个瘦小角色的动画应用到一个高胖驼背的角色上为例:
1、基本操作是将他们的骨骼一一对应,无视具体长短等强行对应
2、在发生旋转时转动的相对角度不变,即目标角色的旋转是在目标角色本身的姿态基础上进行的,而非在世界坐标系下达成和原角色一样的角度。位移和放缩也同理。
3、在发生平移时,除了一一对应外,还需要根据骨骼长度适当调整平移范围,发生放缩时也是根据长度调整。具体来说,我们以角色腰线高度为准,将角色的高低进行适当调整,并且一般位移的速度也会根据腰线高度适当放缩。

另外,还存在一种情况如下图:
在这里插入图片描述

这种时候需要IK去解决

另外,上述所有都是基于大家骨骼架构整体相同的前提,但实际游戏中经常会有不同的,这时候怎么处理呢?
解决办法如下(来自NVIDIA)
在这里插入图片描述
其实就是找到对应的两组骨骼,它们之间的骨骼数可能不同(如上图source是四块,target是三块),然后把之间的骨骼都归一化。针对target骨骼,去找每个骨骼对应source的位置,并适当调整(这里还是可以看一波网课)。

动画重定向目前也有一些亟待解决的问题:
在这里插入图片描述
另外,表情领域的MF也面临动画重定向问题,具体做法有如利用拉普拉斯算子解决artifacts等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795267.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM 内存溢出排查

说明:记录一次JVM内存溢出的排查过程; 场景 项目开发完成后,首次提交到测试环境。测试、产品同事反馈页面先是操作响应慢,抛出超时异常,最后直接无法使用。查看日志后得知是内存溢出。 重启服务后,我对前…

Linux Summary of My Own - Big

DIY Linux Summaries I) Command Lines1.1) difference between "escshifti" and "escshifta"1.2) how to use escape character to have computing on multiplication1.3) file types in Linux I) Command Lines 1.1) difference between “escshifti” …

c语言库函数:时间相关time,localtime,asctime

目录 1.引言 2.时间函数基本信息 2.1 time函数 2.2 local函数 2.3 asctime函数 3.使用demo 1.引言 很多时候,我们需要使用当前时间,怎么获取呢?其实c语言库函数中提供了一些列时间相关的函数,可以从系统中获取时间的方法。…

SV学习笔记(五)

线程的使用 程序和模块 module(模块)作为SV从verilog继承过来的概念,自然地保持了它的特点,除了作为RTL模型的外壳包装和实现硬件行为,在更高层的集成层面,模块之间也需要通信和同步。 对于硬件的过程块&…

如何物理控制另一台电脑以及无网络用作副屏(现成设备和使用)

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 控制另一台电脑有很多方法&…

记录一下前端定时器清除失效的问题

目录 一、问题引入 二、错误代码: 三、错误原因 四、修正的代码 附 vue提供的线上运行代码网址以便证实可用性 一、问题引入 按理说,打开定时器 xxx setInterval(()>{ },100),之后只要 clearInterval(xxx) 就可以顺利关闭定时器…

5.113 BCC工具之nfsslower.py解读

一,工具简介 NFS是一种分布式文件系统协议,允许客户端通过网络访问服务器上的文件。然而,由于网络延迟、服务器负载等原因,NFS操作可能会变得缓慢,从而影响系统性能。 nfsslower 显示慢于阈值的 NFS 读取、写入、打开和 getattr 操作。这有助于我们发现导致NFS性能下降的…

【漏洞复现】用友NC Cloud前台命令执行漏洞

0x01 阅读须知 “如棠安全的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供…

Visual Studio安装下载进度为零已解决

因为在安装pytorch3d0.3.0时遇到问题,提示没有cl.exe,VS的C编译组件,可以添加组件也可以重装VS。查了下2019版比2022问题少,选择了安装2019版,下面是下载安装时遇到的问题记录,关于下载进度为零网上有三类解…

[Spring Cloud] gateway全局异常捕捉统一返回值

文章目录 处理转发失败的情况全局参数同一返回格式操作消息对象AjaxResult返回值状态描述对象AjaxStatus返回值枚举接口层StatusCode 全局异常处理器自定义通用异常定一个自定义异常覆盖默认的异常处理自定义异常处理工具 在上一篇章时我们有了一个简单的gateway网关 [Spring C…

蓝桥杯杯赛之深度优先搜索优化《1.分成互质组》 《 2.小猫爬山》【dfs】【深度搜索剪枝优化】【搜索顺序】

文章目录 思想例题1. 分成互质组题目链接题目描述【解法一】【解法二】 2. 小猫爬山题目链接题目描述输入样例:输出样例:【思路】【WA代码】【AC代码】 思想 本质为两种搜索顺序: 枚举当前元素可以放入哪一组枚举每一组可以放入哪些元素 操…

如何更改WordPress站点的域名:完全指南

更换WordPress网站的域名可能看起来是一个复杂的过程,但只要按部就班,实际上是一个相对直接的任务。无论是因为品牌重塑,还是简单地想要一个更好的域名,这篇文章将引导你通过从旧域名到新域名的整个迁移过程。请仔细遵循以下步骤&…

腾讯云服务器优惠活动价格表_CPU内存带宽报价明细

2024年最新腾讯云服务器租用优惠价格表:轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年,540元三年、2核4G5M带宽218元一年,2核4G5M带宽756元三年、轻量4核8G12M服务器646元15个月;轻量4核16G12M带宽32元1个月、96元3个…

【OpenCV-颜色空间】

OpenCV-颜色空间 ■ RGB■ BGR■ HSV■ HSL■ HUE■ YUV ■ RGB ■ BGR BGR 就是RGB R和B调换位置。 OpenCV 默认使用BGR ■ HSV ■ HSL ■ HUE ■ YUV

数组指针和指针数组

理解数组指针和指针数组之间的区别是很重要的,尤其在C语言中。以下是它们的主要区别: 数组指针(Pointer to an Array): 数组指针是指向数组的指针。 它指向整个数组,而不是数组中的单个元素。 它的声明形…

C#将Console写至文件,且文件固定最大长度

参考文章 将C#的Console.Write同步到控制台和log文件输出 业务需求 在生产环境中,控制台窗口不便展示出来。 为了在生产环境中,完整记录控制台应用的输出,选择将其输出到文件中。 但是,一次性存储所有输出的话,文件会…

环形链表--极致的简便

一、要求 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…

故障诊断 | 一文解决,PLS偏最小二乘法的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | 一文解决,PLS偏最小二乘法的故障诊断(Matlab) 模型描述 偏最小二乘法(Partial Least Squares, PLS)是一种统计建模方法,用于建立变量之间的线性关系模型。它是对多元线性回归方法的扩展,特别适用于处理高维数据和具有多重共线性的数据集。…

Java基础学习:Java agent

文章目录 一、java agent介绍二、Java Agent的应用场景 一、java agent介绍 Java Agent是Java编程语言提供的一种特殊机制,允许在程序运行过程中对字节码进行转换和增强。它通过Java的Instrumentation API来实现,主要用于在应用程序加载类时进行监测、修…