GAMES101课程学习笔记—Lec 21~22:Animation
1 简介
1.1 动画历史 History
动画——让画面动起来
最开始作为一种沟通工具,更具有美学意义,审美通常主导技术
在图形学里可以理解为对建模以及几何的拓展,在不同时间有不同的几何形体
动画形成方式为按顺序查看时的图像序列
- 动画的历史就简述了,从壁画→圆盘播放(如书页画图)→电影的产生→第一次手绘动画:白雪公主→计算机动画→全CG动画……
1.2 关键帧动画 Keyframe animation
如示意图 很好理解
关键帧动画的技术问题在于如何在关键帧之间插值
线性插值通常不够好
更好连续性的插值方法,用曲线以及样条
1.3 物理模拟 Physical simulation
最简单的物理模拟,用牛顿的运动定律
比较复杂的布料模拟以及流体模拟
1.3.1 质点弹簧系统 Mass Spring System
质点弹簧系统做绳子,布料,头发模拟都可以
- 质点弹簧系统是一系列相互连接的质点和弹簧
最基础的单元是一个弹簧左右连俩质点,理想弹簧——没有长度,拉开就有力
胡克定律可以求力
- 但是弹簧正常情况下都有力的作用——rest length
还是胡克定律求力,但是目前没有能量损失,永远不会停 - 此处说明一下速度和加速度的常用记法
- 我们单纯加上摩擦力
它也有问题,会让所有的运动都停下来,表示不了弹簧内部的损耗
- 摩擦力加入内部的因素,和ab的相对速度有关系,并且相对速度还要做投影到ab方向(为了防止比如圆周运动这样的,对内部摩擦力没有什么影响的速度)
- 我们之前考虑一节弹簧,但是我们也得考虑弹簧组合起来会是什么样
- 下面我们不考虑弹簧内部,我们考虑怎么用弹簧模拟一块布
最简单的情况我们考虑组合成一张纸,但是有问题
1 切变会造成影响 下图的结构对角一拉就会变形,然而布是不会变的
2 如果不是平面内的力,布会有抵抗的性质(比如布很难完美对折),然而下图结构没法抵抗
- 然后我们优化,为了抵抗切变
- 我们继续优化,抵抗非平面的弯曲,做法每隔一个点连一个弹簧(红线很弱)
- 这时候效果会好,但是不够精确
之前学过布料的渲染,我们知道结构很复杂
除了质点弹簧系统,还有有限元方法(FEM)等等其他方法,比较难做
1.3.2 粒子系统 Particle Systems
定义每一个粒子的力,然后模拟
粒子间有很多作用,很复杂,如图描述
粒子动画分为模拟与渲染,模拟出力的作用,渲染成不同材质
非常简略的描述如何做粒子动画
粒子的力非常的多……
- 粒子系统进行延伸,只要群体之中的个体,都可以当粒子系统(鸟群,分子结构,人群等等)
1.4 运动学 Kinematics
1.4.1 正向运动学 Forward Kinematics
- 定义不同关节
- 关节的运动得到末端的运动
- 问题,前向运动学虽然简单,但是使用太过物理了,艺术家们喜欢拽着末端来更加直观地控制运动
1.4.2 逆运动学 Inverse Kinematics
由尖端位置反推关节作用为逆运动学
- 逆运动学不好做,很难解
- 逆运动学可能存在很多解
- 人们会采用很多优化方法(随机化算法,梯度下降)去找到真正的位置,而不是真的求角度
1.5 角色绑定 Rigging
绑骨和蒙皮都是Rigging要做的
1.6 动作捕捉 Motion Capture
我们可以通过rigging做动画,也可以捕捉真人的动作的控制点来做动画
优点:真实,方便
缺点:操作复杂,花钱,准备工作多,捕捉数据优劣不一,硬件以及捕捉环境有影响
1.7 动画生产流程
2 模拟方法
2.1 单粒子模拟 Single Particle Simulation
- 规定一个物体在某一个时刻的速度和位置,如何解出某个时间之后它会出现在哪里
下图要求模拟一个粒子在速度场中要如何运动
- 速度场中,在任何一个位置,我们都有它的速度
写出来相当于是常微分方程
- 我们知道速度,想知道任何一个时刻的位置
我们会给出起始位置,以及需要的时间,我们怎么解呢?
2.1.1 欧拉方法 Euler’s Method
- 把时间细分成小块,每一个小块计算位置,不断这么做
考虑每个步长后会到什么位置
始终用前一帧的状态来更新后一帧
(forward 前向、显式)
- 但是这么做有很多问题
比如非常不准,误差大,要步长越细才越准
稳定性不好
只要取了步长就会产生问题,速度场的变化会比步长精细
并且出现问题会被无限放大累计,也就是出现正反馈
用数值方法解微分方程都会出现问题
误差以及稳定性
2.1.2 改善不稳定性
为了提高稳定性有很多方法:中点法,自适应步长法,隐式方法,非基于物理的方法
- 中点法
在使用欧拉方法时,第一次使用得到中点的速度
然后取中点的速度,重新算一遍欧拉方法
中点法准确其实是多了一个二次项
- 自适应步长法
应用欧拉方法得到 X T X_T XT
我们可以算两遍,在t/2处算出结果,然后后半程再算一次,得到 X T / 2 X_T/2 XT/2
如果两者相差很远,再缩小步长
- 隐式欧拉方法
(backward 隐式、后向)
用下一步的速度和加速度
一开始我们还不知道这些未来的数据,我们要解出当下的数据,不太好解
我们认为这个时刻的位置,下个时刻的加速度都知道,解出下个位置的速度和加速度
用优化方法来解,慢很多,但是稳定性好
- 如何定义方法稳不稳定呢?
我们根据局部的误差与总体的误差
我们不关系数据,关心阶数
隐式欧拉是一阶的
(阶数越高越好,减小步长的情况下降低更快)
- Runge-Kutta Families
这类方法擅长解非线性的常微分方程
有一个四阶的方法很好
(建议上数值分析的课,会有用)
- 位置调整法,好用,很快,可能不太物理
2.2 刚体模拟 Rigid Body Simulation
不会形变,内部所有的点都按照同种方式运动
所以刚体也相当于一个粒子,但是计算时会注意更多物理量
2.3 流体模拟 Fluid simulation
- 介绍一种简单的非物理的Position-Based的流体模拟方法:
认为水体由不可压缩的刚体小球组成
认为水不可压缩,密度一致
任何一个时刻可得到小球分布的位置,如果有地方密度变化了,那么就需要移动小球修正不正确的密度
为了修正,我们要知道一个小球位置的变化对其周围密度的影响,导数→梯度
这个修正过程就是梯度下降的过程,会一直运动停不下来,可以人为加入
- 流体模拟中两种不同的思路:Eulerian vs. Lagrangian
Lagrangian:质点法,以每个元素为单位模拟
Eulerian:网格法,以空间为单位分割模拟
- 结合上述的两种方法,MPM方法
认为粒子都有材质属性,模拟的过程在网格里做,然后把网格做的结果写回粒子
3 本系列课程的后续学习路线
课程经常会有人问为什么不教OpenGL,学了光栅化这块之后可以直接手写光栅化渲染器,不手写直接学相应教程也是没有问题
下一步怎么学?
- 如果想继续学习实时渲染,那么就去看《real time rendering》这本书,对照任何OpenGL的编程的书,可以继续学下去了,我们学的变换的各种知识一定比市面上的使用OpenGL教程难
如果学DX,想和实时光线追踪结合在一起,或者vulkan怎么搞跨平台的东西,都是没问题的,可以直接上手 - 几何部分,学更多的数学
- 光线传播部分,可以等闫老师之后的课程《实时高质量渲染》
- 模拟部分可以看games201