动画

动画入门

  1. 让物体活过来
  2. 将场景中的模型放在时间维度上去展示
  3. 电影: 每秒24帧
  4. 视频: 每秒30帧
  5. 虚拟现实: 每秒90帧

动画的历史关键时期

  1. 壁画
  2. 圆盘
  3. 科研用电影
  4. 手绘剧场版
  5. 早期计算机动画
  6. 侏罗纪公园: 恐龙由电脑生成动画
  7. 玩具总动员: 整个由电脑生成
  8. 2009年
  9. 2019年

关键帧动画

  1. 艺术家绘制关键帧,计算机生成插值
  2. 插值不一定是线性,有可能是曲线

物理模拟

  1. 牛顿定律: F = ma
  2. 基于物理的动画: 抛物线,衣服摆动

质点弹簧系统

  1. 是一系列连接的质点和弹簧
  2. a点受到往b方向的力: Fa->b = ks(b-a),Fb->a = -Fa->b,ks为弹簧系数(胡克定律)
  3. 正常弹簧不可能没有长度,假设弹簧完全松弛的长度为l,则Fa->b = ks(b-a)*(|b-a|-l)/(|b-a|)
  4. 存在的问题: 由于能量守恒,会永远的运动下去,加入摩擦力即可
  5. 物理模拟中常用记法,如果x表示位置,则x上加一个点,则表示速度,加2个点则表示加速度
  6. 假设b表示物体的位置,b'表示速度向量,则摩擦力 f = -kd * b',kd为摩擦系数
  7. 存在的问题: 会减慢所有的运动,如果弹簧两个点从高空落下,则会越落越慢,表示不了弹簧内部的摩擦力
  8. 弹簧内部的摩擦力一定是让弹簧回归松弛状态的,如果b的速度要比a速度快,则b上的摩擦力一定越大
  9. 另外由于速度的方向并不一定都是沿着ab方向,所以计算b和a的相对速度的时候,再与ba单位向量做一次点积,可以得到相对速度在ba方向上的投影向量长度,再与ba单位向量相乘,可得投影向量,该向量即是与摩擦力相关
  10. 考虑弹簧上的b点的摩擦力: fb = -kd * ((b - a) / |b - a|) * (b' - a') * ((b - a) / |b - a|),fb最终表示的是一个与ba相对速度相反的向量
  11. 摩擦力与弹簧长度无关
  12. 布料模拟,存在的问题,以及解决方案:
    1. 布料对角线拉伸是不会发生切变的: 给对角线的两个点连线,该线也计算为弹簧
    2. 布料不能被折叠: 给相隔的水平或者垂直的两点连线,该线也计算为弹簧,但弹性系数较小
  13. 有限元方法FEM: 用于车子碰撞

粒子系统

  1. 大量例子的合集,给每一个粒子定义一个力
  2. 粒子越多,渲染越慢,但越精细
  3. 粒子越少,渲染越快
  4. 可以模拟雾,烟尘,流体
  5. 粒子与粒子之间可能有斥力也有引力
  6. 算法:
    1. 如果需要,创建新粒子
    2. 计算每一个粒子的作用力
    3. 更新每个粒子的位置和速度
    4. 如果需要,移除死去的粒子
    5. 渲染粒子
  7. 粒子之间的作用力:
    1. 引力: 电磁力,弹簧力,排斥力
    2. 摩擦力: 粘滞力,空气阻力
    3. 碰撞: 跟墙,容器碰撞,角色身体不能穿模
  8. 万有引力: FG = G * m1m2/d^2
  9. 鸟群模拟:
    1. 每个个体都是往群体聚集
    2. 个体与个体之间存在最小距离,可以理解为斥力
    3. 每个个体一定是往一个大部队的方向飞

运动学

  1. 骨骼类型:
    1. pin: 1D,骨骼被钉在某个点,只能在平面内旋转
    2. ball: 2D,可以在一个球内旋转
    3. prismatic joint: 不仅可以旋转,还可以移动
  2. 调整各个骨骼的旋转角度,计算尖端位置

逆运动学

  1. 调整尖端的位置,自动计算出各个骨骼的旋转角度
  2. 存在的问题: 有可能有多个解,也可能无解

Rigging

  1. 类似木偶操纵,提线来控制动作和造型

Blend Shapes

  1. 定义关键帧,使用插值来做动画

动作捕捉

  1. 可以得到大量的真实数据
  2. 准备起来麻烦
  3. 数据是否可用
  4. 常用的还是身上贴一些标记,如小球,贴片之类的,通过多角度摄像机来捕获
  5. 恐怖谷效应

动画生产流水线

  1. pre-production:
    1. 有个想法
    2. 描述story
    3. 原画师画几幅关键的图
    4. 播放原画幻灯片
    5. 设计师设计具体场景
  2. production:
    1. 场景布置
    2. 建模
    3. 纹理材质
    4. rigging
    5. 做成动画
    6. 准备光照,VFX
    7. 渲染
  3. post-production:
    1. 场景组合
    2. 2D VFX
    3. 调色修复细节问题
    4. final output

单一粒子模拟

  1. 速度场: v(x, t),在任意时间任一点的速度函数
  2. 常微分方程: 单变量的微分方程,dx/dt = x' = v(x, t),已知速度,反推任意时刻的位置
  3. 欧拉方法:
    1. 所有的量都用上一帧的,估计下一帧的值
    2. x[t+dt] = x[t] + dt * x'[t]
    3. x'[t+dt] = x'[t] + dt * x''[t]
    4. 误差: dt越小误差越小
    5. 不稳定性: 稳定性上会出问题,迅速变得不稳定,在圆形速度场中,位置会越来越偏离圆心
  4. 中点法,修正欧拉方法
    1. 先用欧拉方法计算dt之后的目标点a的位置
    2. 取中点b: x[mid] = x[t] + dt/2 * v(x[t], t)
    3. 用中点b的速度来更新位置: x[t+dt] = x[t] + dt * v(x[mid], t)
  5. 自适应改变步长的方法
    1. 先用欧拉方法计算dt之后的目标点a的位置
    2. 取中点b,再从b计算dt/2之后的目标点c的位置
    3. 如果a和c距离足够近,则dt可行,如果很远,则缩减dt的一半循环一次
  6. 隐式欧拉方法
    1. 以未来的速度和加速度来计算
    2. x[t+dt] = x[t] + dt * x'[t+dt]
    3. x'[t+dt] = x[t] + dt * x''[t+dt]
    4. 只有已知未来的加速度的时候才能解出来
    5. 如果是非线性变化,也不好解
    6. 提供了非常好的稳定性
    7. 如何决定稳定性: 计算每一步的误差和整体误差来衡量,整体误差与每一步误差的阶数,隐式方法阶数为1
      1. 每一步误差为O(h^2),整体误差为O(h)
      2. h代表dt,如果dt变为一半,则隐式方法的整体误差也减小一半
      3. 阶数越高,越稳定
    8. 龙格库塔方法: 一系列方法非常擅长解ODE的,特别是对于非线性的情况,有一个4阶的方法应用非常广,简称RK4
      1. 初始条件: dy/dt = f(t,y), y(t0) = y0
      2. y(n+1) = yn + h*(k1 + 2k2 + 2k3 + k4)/6
      3. k1 = f(tn,yn)
      4. k2 = f(tn + h/2, yn + k1 * h/2)
      5. k3 = f(tn + h/2, yn + k2 * h/2)
      6. k4 = f(tn + h, yn + k3 * h)
      7. 《数值分析》了解更多
  7. 基于位置的方法: 不需要经过物理模拟,直接调节位置,快速简单,无法保证能量守恒

刚体的模拟

  1. d(x, a, x', w)/dt = (x', w, F/m, w/dt),其中x为位置,对位置求导是速度,其中a为转动角度,对转动角度求导为角速度,其中x'为速度,对速度求导为加速度,其中w为角速度,对角速度求导为角加速度

流体模拟

  1. 假设水体是有大量的不可压缩的刚体小球组成的
  2. 假设水在任何时刻任何位置都不可被压缩,即密度不变
  3. 因此,任何位置密度发生变化,我们需要调整粒子的位置来修正密度
  4. 我们需要知道任意粒子所在的位置的密度
  5. 梯度下降法
  6. 一般不会停下来,实际过程中会增加能量衰减来让流体停下来

欧拉方法 vs 拉格朗日方法

  1. 两种不同的视角来模拟大量的粒子: 模拟小鸟移动
  2. 质点法(拉格朗日方法): 盯着每一只小鸟,正确模拟每一只小鸟在dt时间的位置
  3. 网格法(欧拉方法): 将空间分成网格,盯着每一个网格随着dt时间的变化
  4. 混合方法: 模拟物体融化
    1. 首先认为每个粒子都携带材质属性
    2. 在空间划分格子,每个格子记录粒子的变化
    3. 把格子里面的信息写回粒子上