负反馈系统在模型动画控制中的应用
最近在解决 3d engine 接口的一处设计问题。我们知道,在 3d 游戏中,engine 的接口设计往往比性能更加重要,这决定了 engine 是否好用,甚至是否能用。简单的功能堆砌不是 engine 。
目前我想弄清楚的一个技术点就是,当模型置入场景后,如果播放的动画本身有位移,引擎应提供怎样的接口,让使用者最为方便的表达他意图。
具体到一个问题点来说,当我们的美术人员制作了一组四足动画奔跑的动画后,怎么在游戏中最自然的表现出来。
就我有限的眼界所知,有许多人在制作 3d engine 时是这么规定的:美术需要把动画调整成原地奔跑的样子。(或者换个方式,在从制作软件中导出时,让原本具有位移的动画变为原地移动)如此,就可以在最终表现时,自由控制播放的速度。
但是稍加思考,就知道这样做导致的图象表现和我们期待的样子是有偏差的。下面让我们来分析一下。
生物在奔跑的时候,重心的移动线速度不可能保持一个完全均匀的速度。脚掌在着地的那一刹那,产生了极大的推力,身体拥有了最大的加速度。但速度本身却是在腾空那一刻加到最大,而到下次着地的过程中是做一个减速运动的。另外,重心也非保证完全平行于地面运动而是有上下起伏。
硬把跑步的动作拉回原地,而在用的时候拉成匀速运动是不准确的。如果美术提供的素材足够真实(比如使用了动作捕捉器)。那么这些变了形的动画信息在游戏中就会被表现成身体在地面滑行,而没有跑步的力量感。
如果让 engine 直接按带位移的方式播放走路、跑步(可能还有格斗时的各种腾挪)动画,那么这些动画实际在世界中移动的距离就需要被了解并参与计算。尤其是有些动画,并没有播放完整一个循环,就被中间打断(往往是改变了移动方向或插入新的动作),导致无法预知其中间状态。
我们在引擎早期设计时,曾经考虑过导出动画信息中的位移信息(其实还包括模型的角度信息,一共是 6 个自由度)。期望中间层可以利用这些信息将动画表现的更真实。
可是在编写代码时,我们发现,利用这些数据并不容易。
经过一番思考后,我发现应该换一条路来解决这个问题。
如果我们了解一丁点自动化控制的理论,就可以知道,提供一个“负反馈”的机制,对系统稳定运行是非常重要且必要的。开环系统远远不如闭环系统稳定,是我在刚进大学不久,课堂上学到的一条重要知识。
其实我们完全不需要知道美术制作的跑步动画,模型在一个循环中移动了多远,节奏有多快。更不需要知道每个时刻动画相对于起始帧(或上一帧)做了怎样了状态(位置和方向)改变。
我们只需要通过接口让 engine 播放指定的动画,并可以随时取得模型的状态信息就够了。也就是说,指定 engine 播放一匹狼奔跑的动画,那么不下达新的指令前,engine 就一直不断的让这匹狼向前奔跑就好了。另外我们需要的是可以查到这匹狼的坐标位置,并可以控制改变动画播放的速度。
注意,这里改变动画播放的速度,并不会改变狼奔跑中每一步跨出的距离,而只是改变了步伐的节奏。
我们不断的测算狼当前的线速度(这可以通过记录上一次查询的时间和坐标,同当前的量相减,并对过去一段时间的测算量做一个加权平均即可。如果发现速度达不到期望的速度,那么就把动画播放速度提高一点点;反之就降低一点的。
最终,这匹狼的奔跑速度就会稳定在我们期望的值上,或在这个值的周围做小幅度震荡。
除了位置的控制外,我们还可以讲角速度也纳入负反馈系统,即可以得到一个相对真实的转弯动画(或许要配合美术更多的资源)。这些道理相通,就不展开写了。
总结一下,最终我们需要的是 engine 提供一个动画播放并切换到其它动画的接口,并在内部完成动作融合。btw, 相关的问题前段时间我写过一篇 blog 。
engine 根据动画信息,负责修改模型的位置以及角度等状态信息。也就是说,动画数据不仅仅是用于表现,还会反作用于模型的状态属性。
需要可以通过 engine 查询模型的状态信息,包括其坐标(相对父节点的坐标),朝向角度。
可以自由的控制动画播放的速度。
我相信,一个优秀的 3d engine 是在这些细节设计的推敲中诞生的,其重要性绝不亚于去应用新型号显卡的高级特性。或许已经有很多制作 3d 游戏或引擎的人已经这样做了,但我也相信,还有人没有这样做,有如想通这个问题前的我。故作此文记录之。
Comments
Posted by: Chang | (15) March 29, 2012 05:53 PM
Posted by: wukaikai | (14) November 26, 2008 04:32 PM
Posted by: tearshark | (13) May 12, 2008 04:10 PM
Posted by: Cloud | (12) April 11, 2008 02:33 PM
Posted by: Spe | (11) April 11, 2008 02:03 PM
Posted by: Cloud | (10) April 10, 2008 10:27 PM
Posted by: Spe | (9) April 10, 2008 04:54 PM
Posted by: Spe | (8) April 10, 2008 04:48 PM
Posted by: 安德尔斯 | (7) April 8, 2008 08:05 AM
Posted by: Anonymous | (6) April 8, 2008 12:13 AM
Posted by: Anonymous | (5) April 6, 2008 04:32 PM
Posted by: Cloud | (4) April 6, 2008 04:27 PM
Posted by: UDDWilliam | (3) April 6, 2008 12:36 PM
Posted by: xLight | (2) April 6, 2008 10:52 AM
Posted by: 知名不具 | (1) April 6, 2008 09:39 AM