一、动画分类
1.1 关键帧动画
在关键的位置上制作一帧画面,而中间的过程采用自动生成的方式形成动画
自动生成可以用线性插值的方式,但是很生硬:
用splines来平滑过度或者有必要的突变则会有更好的动画效果:
但是这样的动画不符合物理规律,只是看起来合适。
1.2 物理模拟(Physical Simulation)
已知物体质量,给物体应用一个力,则可以算出它的加速度,再引入时间,就能算当前时刻速度、位置等一系列信息,然后就可以动态的更新下一时刻的信息从而产生动画了。
物理仿真/模拟背后的核心思想就是构建物理模型,分析受力,从而算出某时刻的加速度、速度、位置等信息。
只要能够正确建立物理模型,一定可以得出正确的物理模拟结果。
1.3 质点弹簧系统(Mass Spring System)
一系列相互连接的质点和弹簧:
简单、理想化的弹簧(帮助理解)
- 没有长度
- 弹簧拉多长就产生多大的力
- 受力计算方法如下,只有将质点向内拉的力,ks 为弹性系数。
正常的有长度的弹簧
- 弹簧被拉长会产生向内收缩的力,被压短则产生外推力
- 弹簧常态长度为 l,受力大小依然形变大小成正比,计算方式如下
存在的问题:永远震荡不会停止,动能与势能不停转变,没有损耗。
1)简单的引入阻尼(错误方法)
介绍如下记号,打点表示对时间 t 求导,位移x求导1次是速度,求导2次为加速度。(简单物理)
简单的阻尼表示:与速度反向相反,在数学中的表示如下,其中kd 为阻尼系数,
引入简单阻尼产生的bug:他会减慢一切运动。
(理解:我们引入阻尼真正的目的是让震荡的弹簧不会永远震荡下去,会因为阻尼的存在而停下。目前引入的阻尼确实能达到目的,但还会阻止一个处于常态的弹簧的一切非震荡运动。比如弹簧两端相对静止,但是处于自由落体状态,都有向下的速度,则此阻尼力会使他落得越来越慢,这不正常)
2)引入弹簧内部阻尼(正确方法)
限制阻尼只发生在弹簧内部,只作用于因弹簧形变引起的运动。
未达目的,必须引入相对运动,公式更改如下(注意这里算阻尼跟伸缩长度没关系)
弹簧结构: 不同弹簧的组合,会有不同的性质,可以模拟不同的物品。
布料模拟推导过程:
序号 | 结构 | 说明 |
---|---|---|
0 | ![]() | 不能模拟布料,因为它不具备布的特性(不能抵抗切力、不能抵抗对折力(布料多少有点抵抗对折的能力,因为它不能像纸一样被折叠)) |
1 | ![]() | 改进了一点,虽然能抵抗图示对角线的切力,但是存在各向异性。依然不能抵抗折叠。 |
2 | ![]() | 可以抵抗切力,有各向同性,不抗对折 |
3 | ![]() | 红色skip connection,注意红线的力比较小。现在可以比较好的模拟布料 |
1.4 粒子系统(Particle Systems)
- 建模一堆微小粒子,定义每个粒子会受到的力(粒子之间的力、来自外部的力、碰撞等)
- 在游戏和图形学中非常流行,很好理解、实现
最简单的实现算法:
- 动画的每一帧
- 创建新的粒子(如果需要)
- 计算每个粒子的受力
- 更新每个粒子的位置和速度
- 结束某些粒子生命(如果需要)
- 渲染
1.5 正向运动学(Forward Kinematics)
1)骨骼动画
骨骼系统
- 拓扑结构
- 关节相互的几何联系
- 树状结构
关节类型
- Pin(滑车关节):平面内旋转
- Ball(球窝关节):一部分空间内旋转
- Prismatic joint(导轨关节):允许平移
例:由两部分骨骼构成的2D的手臂
第一部分旋转θ1,第二部分旋转θ2,问端点p的位置在哪?
1.6 逆运动学(Inverse Kinematics)
正向运动学:通过骨骼旋转角度计算尖端位置
逆向运动学:通过控制尖端位置,反算出应该旋转多少
例:依然是最简单的2部分组成的手臂
知道p点位置,反算骨骼角度
逆运动学存在的问题:
1.解并不唯一,两种不同的角度组合方式都能让p处于目标位置
2.并不是一定有解,即会有无解的情况,如下图尖端活动范围有限
1.7 动画绑定(Rigging)
rigging是一种对角色更高层次的控制,允许更快速且直观的调整姿势、表情等
皮影戏就有点这个味道,但是提线木偶对表情、动作的控制更贴切一些
在角色身体、脸部等位置创造一系列控制点,艺术家通过调整控制点的位置,带动脸部其他从点移动,从而实现表情变化,动作变化等。
缺点:需要艺术能力也需要技术,全手工制作费时费力费钱。
Blend Shapes:直接在两个不同关键帧之间做插值,注意是对其表面的控制点做插值
1.8 动作捕捉(Motion capture)
在真人身上放置许多控制点,在不同时刻对人进行拍照,记录控制点的位置,同步到对应的虚拟人物上。
优点
- 快速获得大量真实数据
- 非常真实
缺点
- 昂贵、准备工作麻烦
- 捕捉的动画跟预期艺术需要不太符合,需要调整
- 控制点被遮挡问题
众多动捕设备中最常用的还是光学动捕设备
- 最重要的被遮挡问题,可以通过增加摄像机等方法避免
阿凡达面部动捕:
1.9 动画电影生产线(Pipeline)
总之费钱、费艺术家
二、单粒子模拟(Single Particle Simulation)
学习单个粒子的运动,之后再推广到多粒子系统
- 假设粒子的运动由速度矢量场决定,速度场是关于位置和时间的函数:v(x, t)
- 速度场:定义质点在任何时刻在场中任何位置的速度。给个位置和时间,就能知道速度
- 如下图,箭头方向是速度方向,曲线是粒子在这个速度场中的运动轨迹(粒子0时刻位置知道,以后每个时刻速度都根据速度场进行变化,由于速度变化,位置也会跟随时间产生变化,从而形成的轨迹)
常微分方程 :已知速度,建立方程,解常微分方程就可以得到位置量
2.1 欧拉方法(Euler Method)
(1) 已知 t 时刻的位置和速度,求下一时刻 t + Δt 的位置(注意右上角的角标仅表示时刻信息)
(2) 已知 t 时刻的速度和加速度,求下一时刻 t + Δt 的速度
1)欧拉方法的误差
- 如果采用较大的Δt,误差会很大,并且误差会积累
- 可以通过缩小Δt来控制误差
2)欧拉方法的不稳定性
-
与误差无关,不管取多小的时间差,最后的结果都会和正确结果相差无限远。
-
假设有一个圆形速度场,速度一直是垂直于直径的,按理来说粒子在这里会一直做圆周运动不会飞出去,但是用欧拉方法,不管选择多小的步长Δt,粒子都会飞出去
- 假设如下速度场,粒子初始点在下方,会被下方速度场推到右上方,又被上方的速度场推向右下方,如此交替往复。但是这个速度场,这样的粒子初始位置,正确的路径应该是沿着速度场,缓慢向中间靠拢,最后收敛于中间。
2.2 对抗不稳定性的方法
1) 中点法(Midpoint method)
- 欧拉方法计算质点 t 时刻经过Δt之后的位置a
- 弃用a点选择其中点位置b,得到中点处的速度矢量
- 用中点的速度,计算初始点经过Δt后的位置c
- 如下两个式子,先计算中点b的位置xmid,然后得到t时刻xmid处的速度**v(xmid, t)**算位置c
2)变形欧拉法(Modified Euler)
取开始和结束位置的速度的平均速度,再计算最终位置
3)自适应步长(Adaptive Step Size)
- 基于误差估计,自动选择步长Δt
- 非常实用
- 但是可能会让步长变得特别小
实现步骤
- 先用步长 T 做一次欧拉计算 XT
- 再用步长 T/2 做两次欧拉得到 XT/2
- 比较两次位置误差error ||XT - XT/2||
- if(error > threshold) 减少步长,重复上面步骤
所以如果误差error很大,就会往下细分,直到误差够小为止,这样可以模拟出比较好的效果如右图。拐弯的地方一般步长会比较小。![]()
![]()
4) 隐式欧拉方法(Implicit Euler Method)
- 跟欧拉方法唯一的区别是:用下一个时刻的速度和加速度来计算下一个时刻的位置和速度
- 但是下一个时刻的速度和加速度我们并不知道,所以搞出来是个方程组,这个不好解。。
- 这个方法提供比较好的稳定性。
怎么定义稳定性?
- 局部截断误差(local truncation error):每一步的误差
- 全局累积误差(total accumulated error):总的累积误差
三、 刚体模拟(Rigid Body Simulation)
模拟刚体很简单
- 刚体不会发生形变
- 类似于粒子系统,刚体相当于内部所有粒子以相同方式运动
- 不同的是刚体的模拟中,会考虑更多的属性
- 有以下属性,可以根据前面提到的欧拉方法或者各种其他稳定性好的方法得出经过Δt以后的位置、角度等信息
四、流体模拟(Fluid Simulation)
4.1 基于位置的方法(Position-Based Method)
通过形成一些小球,通过它们的位置来模拟水和浪花。基于位置的方法不是物理的,没有能量损失,虽然可以人为的加入能量衰减
主要思想
- 水是由一个个刚体小球组成的
- 水不能被压缩
- 任何一个时刻,某个位置的密度发生变化(不同于平静水时该空间的小球的密度),就必须通过移动小球的位置进行密度修正
- 需要知道任何一个位置的密度梯度(这是机器学习的梯度下降)
- gradient descent梯度下降