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