跳转到主要内容

12|动画与模拟

动画基础(关键帧与插值、物理模拟);质点弹簧系统(胡克定律、非零长度弹簧、内部阻尼、结构/剪切/弯曲弹簧、有限元方法);粒子系统(受力分析、万有引力、群体模拟、基于位置的流体);运动学(关节骨架、正向与逆向运动学、Style-Based IK、Rigging、Blend Shapes、动作捕捉与恐怖谷、制作流程);常微分方程求解(显式欧拉、误差与不稳定性、中点法、修正欧拉、自适应步长、隐式欧拉、Runge-Kutta、Verlet 积分);刚体模拟与流体模拟(欧拉法与拉格朗日法、SPH、Stable Fluids、物质点方法 MPM)

  • 课程主讲:闫令琪 (Lingqi Yan) | UCSB
  • B站课程链接:https://www.bilibili.com/video/BV1X7411F744
  • 本章对应课件:第 21 讲(Animation 1: Basic Concepts, Mass-Spring Systems, Kinematics, Rigging / Blend Shapes / Motion Capture)、第 22 讲(Animation Cont.: Solving ODEs, Rigid Body and Fluids)

说明:前面十一篇处理的都是"静态"的问题——一个场景摆在那里,我们关心怎么把它算出来、画出来。这一篇换了个维度:让场景随时间动起来。动画和模拟表面上都在"生成运动",但走的是两条完全不同的路:动画是"描述运动"(人给出关键帧或关节角度,计算机负责插值),模拟是"推导运动"(人给出物理规律,计算机负责积分)。两条路在工程上会汇合到同一个地方——都要数值求解微分方程,也都可能因为离散化而崩溃。


1 动画基础 (Animation Basics)

动画 (Animation) 即"让事物活起来"(Bring things to life)。它既是通信工具(视觉信息的传达),也是建模的扩展(把场景模型表示为时间的函数),最终输出为一串按顺序观看时产生运动感的图像序列。

不同应用对帧率的要求

应用场景帧率 (fps)说明
电影24 fps传统电影标准
视频30 fps一般视频标准
虚拟现实 (VR)90 fps高帧率防止眩晕

动画的历史发展

时间事件意义
3200 BCE伊朗陶碗动画已知最早的动画
1831幻透镜 (Phenakistoscope)早期动画装置
1878Muybridge “Sallie Gardner”第一部电影(科学工具)
1937迪士尼《白雪公主》首部长篇手绘动画电影
1963Sutherland “Sketchpad”首个计算机生成动画
1972Catmull & Parke 计算机人脸早期计算机动画
1993《侏罗纪公园》数字恐龙
1995皮克斯《玩具总动员》首部 CG 长片电影
2009索尼动画《天降美食》(Cloudy with a Chance of Meatballs)十年前(相对当时)的计算机动画水准
2019迪士尼《冰雪奇缘 2》(Frozen 2)2019 年的计算机动画水准

这张表其实是一个很直观的"摩尔定律"式观察:从上到下每格之间的技术跨度,大致与时间跨度成正比,而 1963 年的 Sketchpad 到 1995 年的《玩具总动员》用了三十年,1995 到 2019 只用了二十四年。

关键帧动画 (Keyframe Animation)

核心思想是把动画的制作分两层:

  • 关键帧 (Keyframes):由主动画师创作的重要帧
  • 中间帧 (Tweens):由助手或计算机自动生成的过渡帧(“tweening”)

关键帧动画示意

关键帧插值的做法是把每一帧看作一个参数值的向量,对每个参数分别插值。线性插值通常不够好,需要使用样条 (splines) 进行平滑、可控的插值。

关键帧插值曲线对比(线性 vs 样条)

物理模拟 (Physical Simulation)

物理模拟的出发点是牛顿定律:

$$ \mathbf{F} = m\mathbf{a} $$

其中 $\mathbf{F}$ 为力,$m$ 为质量,$\mathbf{a}$ 为加速度。基于物理的动画即使用数值模拟生成物体运动,例如从当前状态外推下一步:

$$ \mathbf{x}^{t+\Delta t} = \mathbf{x}^{t} + \Delta t \, \mathbf{v}^{t} + \frac{1}{2}(\Delta t)^2 \mathbf{a}^{t} $$

常见的应用有三类:

应用说明
布料模拟用质点弹簧系统模拟织物
流体模拟模拟水、烟等流体效果
绳索 / 毛发弹簧链或质点系统

布料模拟效果 & 流体模拟效果


2 质点弹簧系统 (Mass Spring Systems)

质点弹簧系统是建模动态系统的经典方法:用弹簧连接质点,来模拟布料、绳索、毛发等。它大概是整个图形学里"投入产出比"最高的模拟方法——原理只有一条胡克定律,却能撑起布料、头发、软体一大片应用。

点的导数表示法 (Dot Notation)

设 $\mathbf{x}$ 为某个点的位置向量,用点号表示对时间的导数:

符号含义关系
$\mathbf{x}$位置—
$\dot{\mathbf{x}}$速度 $\mathbf{v}$位置对时间的一阶导数
$\ddot{\mathbf{x}}$加速度 $\mathbf{a}$位置对时间的二阶导数

理想弹簧(胡克定律)

两个端点 $a$ 和 $b$,弹簧将两点拉向一起,力与位移成正比(胡克定律 Hooke’s Law):

$$ \mathbf{f}_{a \to b} = k_s(\mathbf{b} - \mathbf{a}) $$$$ \mathbf{f}_{b \to a} = -\mathbf{f}_{a \to b} $$

其中 $k_s$ 为弹簧系数(刚度 stiffness)。

质点弹簧

问题:理想弹簧的静止长度为零,会一直把两点拉到重合。

非零长度弹簧 (Non-Zero Length Spring)

引入静止长度 $l$ (rest length),弹簧在长度为 $l$ 时不施力:

$$ \mathbf{f}_{a \to b} = k_s \frac{\mathbf{b} - \mathbf{a}}{\|\mathbf{b} - \mathbf{a}\|} \left( \|\mathbf{b} - \mathbf{a}\| - l \right) $$

公式可以拆成三部分看:

部分含义
$\frac{\mathbf{b} - \mathbf{a}}{\|\mathbf{b} - \mathbf{a}\|}$从 $a$ 指向 $b$ 的单位方向向量
$\|\mathbf{b} - \mathbf{a}\| - l$当前长度与静止长度之差(标量)
$k_s$弹簧刚度系数

问题:这样的弹簧会永远振荡(没有能量损失),因此需要引入阻尼。

内部阻尼 (Internal Damping)

最朴素的想法是直接加一个和速度成正比的阻力:

$$ \mathbf{f} = -k_d \dot{\mathbf{b}} $$

这类似于粘性阻力,但它会减慢所有运动(包括整体的平移和旋转)——而我们只希望减慢弹簧驱动的内部运动,并不希望整体下落也变慢。

弹簧内部阻尼的做法是只对弹簧长度变化方向施加粘性阻力:

$$ \mathbf{f}_{a \to b} = -k_d \left( \frac{\mathbf{b} - \mathbf{a}}{\|\mathbf{b} - \mathbf{a}\|} \cdot (\dot{\mathbf{b}} - \dot{\mathbf{a}}) \right) \frac{\mathbf{b} - \mathbf{a}}{\|\mathbf{b} - \mathbf{a}\|} $$

关键点:

  • 阻尼力只作用于弹簧长度变化的方向
  • 不会减慢弹簧系统的整体运动(如全局平移或旋转)
  • $k_d$ 为阻尼系数

值得多看一眼这个式子:$\frac{\mathbf{b}-\mathbf{a}}{\|\mathbf{b}-\mathbf{a}\|}$ 是弹簧轴向单位向量,$(\dot{\mathbf{b}}-\dot{\mathbf{a}})$ 是两端点的相对速度。两者做点积,就取出了相对速度在弹簧轴向上的分量;再乘回单位向量,就把这个标量变回沿轴向的力。垂直于弹簧方向的相对速度(也就是整体旋转)被点积直接过滤掉了——这正是"只阻尼内部形变"的实现方式。

弹簧结构 (Structures from Springs)

按用途,弹簧结构可分为三大类:Sheets(片状,如布料)、Blocks(块状,如三维体)、Others(其他,如绳链等)。

弹簧的行为由其连接结构决定,不同结构具有不同的物理特性:

结构抗剪切抗弯曲特点
结构 1(仅横竖连接)否否无法抵抗剪切和面外弯曲
结构 2(加对角线)是(有各向异性)否可抗剪切,但有方向偏差
结构 3(双对角线)是(偏差较小)否抗剪切更均匀,但仍不抗弯曲
结构 4(加跳跃连接)是是完整结构,红色的跳跃弹簧应弱很多

弹簧结构对比

对应地有三种弹簧类型:

  1. 结构弹簧 (Structural Springs):横竖连接,维持基本形状
  2. 剪切弹簧 (Shear Springs):对角线连接,抵抗剪切变形
  3. 弯曲弹簧 (Bending Springs):跳跃连接(隔一个质点),抵抗面外弯曲,刚度应远小于前两者

最后这点容易被忽略:弯曲弹簧跨越的距离更长,若刚度与结构弹簧相当,整块布会硬得像铁皮。正因为要弱得多,它在结构图里才被画成红色这样"次要"的颜色。

应用示例

应用说明
绳索质点弹簧链模拟绳索
头发弹簧链模拟毛发
布料网格质点弹簧网格模拟织物,可结合数据驱动的弹性模型
裙装 + 角色弹簧裙装与角色身体碰撞的综合模拟

质点弹簧裙装 + 角色综合应用

有限元方法 (FEM)

除了弹簧系统,还可以使用有限元方法 (Finite Element Method, FEM) 来模拟弹性体。FEM 通过将连续体离散为有限个单元,直接求解偏微分方程,比质点弹簧系统更精确,但计算也更复杂。


3 粒子系统 (Particle Systems)

基本概念

粒子系统把动态系统建模为大量粒子的集合,每个粒子的运动由一组物理(或非物理)的力定义。

优点:

  • 易于理解和实现
  • 可扩展:粒子少则快,多则精细

挑战:

  • 可能需要大量粒子(如流体)
  • 可能需要加速结构(如查找邻近粒子用于交互)

粒子系统算法

每一帧动画的更新流程:

For each frame in animation:
    1. [如果需要] 创建新粒子
    2. 计算每个粒子上的力
    3. 更新每个粒子的位置和速度
    4. [如果需要] 移除死亡的粒子
    5. 渲染粒子

注意这个循环里"创建"和"移除"是可选的——正是这两步的可选性让粒子系统能表达火焰、烟雾、浪花这类有生命周期的现象:粒子被发射、存活若干帧、然后消失。

粒子受力分析

力类型示例
吸引 / 排斥力重力、电磁力
弹簧力 / 推力弹簧连接、推进器
阻尼力摩擦、空气阻力、粘性
碰撞力墙壁、容器、固定物体、动态物体、角色身体部位

引力 (Gravitational Attraction)

粒子间的引力服从牛顿万有引力定律:

$$ F_g = G \frac{m_1 m_2}{d^2} $$

其中:

  • $G = 6.67428 \times 10^{-11} \, \text{N}\cdot\text{m}^2\cdot\text{kg}^{-2}$(万有引力常数)
  • $m_1, m_2$ 为两粒子质量
  • $d$ 为两粒子间距离

应用示例:星系模拟(盘状星系模拟,NASA Goddard)。

星系模拟 & 基于粒子的流体

群体模拟 (Simulated Flocking)

把每只鸟建模为一个粒子,受简单力作用,通过数值模拟演化大型粒子系统,就能产生涌现 (emergent) 的复杂行为:

力作用
吸引 (attraction)向邻居中心吸引
排斥 (repulsion)远离过近的个体邻居
对齐 (alignment)朝向邻居的平均轨迹方向

群体模拟三种力

这三种力各自都极其简单,但合在一起就产生了"鸟群"这种谁也没有单独设计过的整体行为。这种涌现行为在鱼群、蜂群等自然界中也能观察到。

其他应用示例

  • 基于位置的流体 (Position Based Fluids):Macklin and Müller 用大量粒子配合密度约束模拟不可压缩水体
  • 分子动力学:冰晶融化模型,通过粒子间相互作用展现冰融化为水的过程
  • 人群模拟:Crowds + “Rock” Dynamics,大规模人群与"摇滚"动力学结合的粒子模拟

人群模拟 Crowds + Rock Dynamics 示例


4 运动学 (Kinematics)

关节骨架 (Articulated Skeleton)

人形关节骨架示例

骨架由三件事描述:

  • 拓扑结构:什么连接到什么(一般是树结构,无环时)
  • 几何关系:由关节定义
  • 关节类型:
关节类型自由度说明
销关节 (Pin)1D 旋转绕轴旋转
球关节 (Ball)2D 旋转任意方向旋转
棱柱关节 (Prismatic)平移沿轴滑动

正向运动学 (Forward Kinematics)

正向运动学两段臂

核心思想:动画师提供关节角度,计算机确定末端执行器 (end-effector) 的位置。

以二维两段臂为例(注意:这里是 Z 轴向上的坐标系):

$$ p_x = l_1 \sin(\theta_1) + l_2 \sin(\theta_1 + \theta_2) $$$$ p_z = l_1 \cos(\theta_1) + l_2 \cos(\theta_1 + \theta_2) $$

其中 $l_1, l_2$ 为两段臂的长度,$\theta_1, \theta_2$ 为关节角度。动画描述则是把这些角度参数值写成时间的函数。

优点缺点
直接控制,方便运动可能与物理不一致
实现简单对动画师耗时

注意"Z 轴向上"这个前提很重要:由于 $\theta$ 是从 Z 轴量起的,第一段臂的分量写成 $(\sin\theta_1, \cos\theta_1)$ 而不是常见的 $(\cos\theta_1, \sin\theta_1)$。照抄习惯写法会让整个骨架躺倒 90°。

行走循环动画示例

逆向运动学 (Inverse Kinematics)

核心思想:动画师提供末端执行器的位置,计算机必须确定满足约束的关节角度——正好和正向运动学反过来。

逆向运动学示意

解析求解(两段臂):对两段臂这种简单结构,可以直接解析求解。由余弦定理可得:

$$ \theta_2 = \cos^{-1}\left(\frac{p_z^2 + p_x^2 - l_1^2 - l_2^2}{2 \, l_1 \, l_2}\right) $$

数值求解方法:对于更复杂的骨架结构,通常无法解析求解,需要使用数值方法(如梯度下降、雅可比矩阵等迭代方法)。

方法适用场景
解析法简单结构(如两段臂)
数值法复杂结构,通用性强

IK 的难点:

  • 可能存在多个解
  • 可能无解(目标不可达)
  • 数值方法可能收敛到局部最优

上面那个 $\cos^{-1}$ 的形式本身就暗示了第一个难点:$\theta_2$ 和 $-\theta_2$ 给出同一个 $\cos$ 值,对应"肘向上"和"肘向下"两个不同的姿势,计算机无从判断该选哪个——这通常要靠额外约束(比如关节角度范围)来消歧。

Style-Based IK(基于风格的逆运动学)

基于风格的逆运动学(Grochow et al., Style Based Inverse Kinematics, 2004)的思路是:不在原始关节空间里求解 IK,而是在从数据中学习得到的姿态空间里求解,使解符合特定角色的运动风格。这样"像不像这个人"就被编码进了求解的约束里。

Rigging(骨骼绑定)

Rigging 是角色上的一组高级控制,用于更快速、直观地修改姿势、变形和表情等。

要点说明
类比如同提线木偶上的线
覆盖范围能捕获所有有意义的角色变化
因角色而异每个角色需要单独绑定
创建成本高——纯手工制作,需要艺术与技术的双重训练

Rigging 面部控制示例

Blend Shapes(变形形状)

Blend Shapes 不使用骨架,而是直接在不同表面之间插值:

  • 典型应用:为一组面部表情建模,在表情表面之间直接插值
  • 最简单方案:取对应顶点位置的线性组合
  • 权重控制:权重随时间的变化可用样条控制

Blend Shapes 面部表情插值示例

Motion Capture(动作捕捉)

定义:数据驱动的动画创作方法——记录真实世界的表演(如人物执行一项活动),并从采集的数据中提取姿态随时间的变化。

优点缺点
可快速捕获大量真实数据设备复杂、成本高昂
真实感可以很高采集的动画可能不符艺术需求,需要再加工

设备分三类:

类型原理特点
光学 (Optical)反光标记 + 红外相机主流方案,精度高
磁学 (Magnetic)感应磁场推断位置 / 朝向需要系绳 (tethered)
机械 (Mechanical)直接测量关节角度限制运动

动捕设备三类对比

光学动捕细节:

  • 在表演者身上粘贴回射反光标记 (retroreflective markers)
  • 配合红外照明与红外相机
  • 位置由多台相机三角测量确定
  • 通常需要 8 台以上相机,采样率 240 Hz
  • 遮挡 (occlusions) 难以处理

光学动捕工作室

运动数据提取并非平凡任务:从采集的行走运动中提取出运动曲线的一个子集,就已经能看出其复杂性(Witkin and Popovic, 1995)——拿到一堆点云和拿到"可用的动作"之间隔着相当多的工作。

恐怖谷 (Uncanny Valley):在机器人与图形学中,当人工角色的外观接近人类真实感时,观众的情绪反应反而会变差,直到角色的表现力达到足够令人信服的真实水平。课件对比了卡通风格(《勇敢传说》,皮克斯)与半真实风格(《极地特快》,华纳兄弟)两类角色。

面部动作捕捉:《阿凡达》将面部动捕用于把演员表情映射到虚拟角色上。

The Production Pipeline(动画制作流程)

整部动画的工业流程是:先建模 (Modeling),再做绑定 (Rigging),随后通过动画 (Animation) 与模拟 (Simulation) 生成运动,最终渲染 (Rendering) 输出成品。

动画制作流程图


5 常微分方程求解 (Solving ODEs)

单粒子模拟

先研究单个粒子的运动,再推广到多粒子。

假设粒子的运动由速度向量场 $\mathbf{v}(\mathbf{x}, t)$ 决定(位置和时间的函数)。计算粒子随时间的位置,就是在求解一个一阶常微分方程 (ODE):

$$ \frac{d\mathbf{x}}{dt} = \dot{\mathbf{x}} = \mathbf{v}(\mathbf{x}, t) $$
  • “一阶”:只取一阶导数
  • “常”:没有偏导数,$\mathbf{x}$ 只是 $t$ 的函数

给定初始位置 $\mathbf{x}_0$,通过前向数值积分求解。

速度场中的粒子运动轨迹

显式欧拉法 (Explicit Euler / Forward Euler)

显式欧拉法

方法:简单迭代方法,常用但不精确,多数情况下不稳定。

$$ \mathbf{x}^{t+\Delta t} = \mathbf{x}^{t} + \Delta t \, \dot{\mathbf{x}}^{t} $$$$ \dot{\mathbf{x}}^{t+\Delta t} = \dot{\mathbf{x}}^{t} + \Delta t \, \ddot{\mathbf{x}}^{t} $$

即用当前时刻的速度和加速度直接外推下一步的位置和速度。

误差与不稳定性

数值积分使用有限差分会导致两个问题:

1. 误差 (Errors):

  • 每个时间步的误差累积
  • 精度随模拟进行而下降
  • 在图形学应用中,精度可能不是最关键的

2. 不稳定性 (Instability):

  • 误差可以复合,导致模拟发散(即使底层系统不发散)
  • 不稳定性是模拟中的根本问题,不可忽略
  • 灾难性实例:PUBG(绝地求生)中载具物理因数值不稳定而发散的演示

误差来源:时间步 $\Delta t$ 越大,误差越大,越容易发散。

显式欧拉法简单但精度低(一阶),且对刚性方程和振荡系统容易不稳定。物理模拟中常用半隐式欧拉或 Verlet 替代,刚性场景则需要隐式方法。

对抗不稳定性的方法

方法核心思想
中点法 / 修正欧拉取起点和终点速度的平均
自适应步长比较一步和两半步,递归直到误差可接受
隐式方法使用下一时间步的速度(更难但更稳定)
基于位置 / Verlet 积分时间步后约束粒子位置和速度

中点法 (Midpoint Method)

中点法

步骤:

  1. 延伸最初的位置,计算欧拉步(得到中间预测位置)
  2. 计算中点处的导数
  3. 用中点导数更新位置
$$ \mathbf{x}_{mid} = \mathbf{x}(t) + \frac{\Delta t}{2} \mathbf{v}(\mathbf{x}(t), t) $$$$ \mathbf{x}(t + \Delta t) = \mathbf{x}(t) + \Delta t \, \mathbf{v}(\mathbf{x}_{mid}, t) $$

修正欧拉 (Modified Euler)

取步长起点和终点速度的平均,效果更好:

$$ \mathbf{x}^{t+\Delta t} = \mathbf{x}^{t} + \frac{\Delta t}{2}\left(\dot{\mathbf{x}}^{t} + \dot{\mathbf{x}}^{t+\Delta t}\right) $$$$ \dot{\mathbf{x}}^{t+\Delta t} = \dot{\mathbf{x}}^{t} + \Delta t \, \ddot{\mathbf{x}}^{t} $$

代入消元后得到:

$$ \mathbf{x}^{t+\Delta t} = \mathbf{x}^{t} + \Delta t \, \dot{\mathbf{x}}^{t} + \frac{(\Delta t)^2}{2} \ddot{\mathbf{x}}^{t} $$

这与物理中匀加速运动的位移公式完全一致。

自适应步长 (Adaptive Step Size)

自适应步长根据误差估计选择步长,非常实用但可能需要很小的步长。

动态调整每一步的步长 Δt

算法:

重复直到误差低于阈值:
    1. 用大小为 T 的欧拉步计算 x_T
    2. 用两个大小为 T/2 的欧拉步计算 x_{T/2}
    3. 计算误差 ||x_T - x_{T/2}||
    4. 如果误差 > 阈值,减小步长并重试

优点:自动适应不同区域的精度需求。

缺点:可能需要极小的步长,计算量不可预测。

隐式欧拉法 (Implicit Euler / Backward Euler)

隐式欧拉法用下一时刻的导数更新状态,因此需要解隐式方程。它的精度只有一阶,但具有无条件稳定性,特别适合刚性方程和需要大步长的场景。与显式欧拉法的唯一区别就在于:用的是下一时刻的导数,而不是当前时刻的。

$$ \mathbf{x}^{t+\Delta t} = \mathbf{x}^{t} + \Delta t \, \dot{\mathbf{x}}^{t+\Delta t} $$$$ \dot{\mathbf{x}}^{t+\Delta t} = \dot{\mathbf{x}}^{t} + \Delta t \, \ddot{\mathbf{x}}^{t+\Delta t} $$

求解方法:需要求解关于 $\mathbf{x}^{t+\Delta t}$ 和 $\dot{\mathbf{x}}^{t+\Delta t}$ 的非线性方程组,通常使用求根算法(如牛顿法)。

稳定性分析:使用局部截断误差(每步)和总累积误差(整体)来衡量:

误差类型隐式欧拉
局部截断误差$O(h^2)$
全局截断误差$O(h)$

其中 $h$ 为步长(即 $\Delta t$)。$O(h)$ 的含义:如果步长减半,误差也大致减半。

显式和隐式在这里形成了一个很典型的权衡:隐式方法的每一步都贵得多(要求解非线性方程组),但允许的步长可以大得多;显式方法每一步便宜,但步长稍大就会炸。工程上选哪个,取决于问题有多"刚性"。

Runge-Kutta 方法 (RK4)

经典四阶 Runge-Kutta 方法 (RK4) 是数值求解常微分方程最常用的方法之一。它通过在一步内计算四次斜率并加权平均,达到四阶精度,在精度、稳定性和计算量之间取得了很好的平衡,特别擅长处理非线性问题。

初始条件:

$$ \frac{dy}{dt} = f(t, y), \quad y(t_0) = y_0 $$

RK4 解:

$$ y_{n+1} = y_n + \frac{h}{6}(k_1 + 2k_2 + 2k_3 + k_4) $$$$ t_{n+1} = t_n + h $$

其中四个斜率为:

$$ k_1 = f(t_n, \, y_n) $$$$ k_2 = f\left(t_n + \frac{h}{2}, \, y_n + h\frac{k_1}{2}\right) $$$$ k_3 = f\left(t_n + \frac{h}{2}, \, y_n + h\frac{k_2}{2}\right) $$$$ k_4 = f(t_n + h, \, y_n + h \, k_3) $$
斜率含义
$k_1$起点斜率
$k_2$中点斜率(用 $k_1$ 估计)
$k_3$中点斜率(用 $k_2$ 估计)
$k_4$终点斜率(用 $k_3$ 估计)

RK4 的精度:局部截断误差 $O(h^5)$,全局截断误差 $O(h^4)$,远高于欧拉法。

权重的 $1:2:2:1$ 很有意思:两个中点斜率各占两倍权重,起点和终点各占一倍——这和辛普森积分公式的权重完全一样,并非巧合,两者都来自同一类高阶近似思想。

基于位置的积分 / Verlet 积分 (Position-Based / Verlet Integration)

思想:

  1. 在修正欧拉前向步之后,约束粒子位置以防止发散和不稳定行为
  2. 用约束后的位置反推速度
  3. 这两种操作都会耗散能量,从而稳定模拟
优点缺点
快速简单非物理基础,耗散能量(引入误差)

6 刚体模拟 (Rigid Body Simulation)

刚体模拟是粒子模拟的简单扩展,只需考虑更多属性。

状态向量:

$$ \frac{d}{dt} \begin{pmatrix} \mathbf{X} \ \theta \ \dot{\mathbf{X}} \ \omega \end{pmatrix}

\begin{pmatrix} \dot{\mathbf{X}} \ \omega \ \mathbf{F}/M \ \Gamma/I \end{pmatrix} $$

符号含义
$\mathbf{X}$位置
$\theta$旋转角度
$\dot{\mathbf{X}}$速度
$\omega$角速度
$\mathbf{F}$力
$\Gamma$力矩 (torque)
$M$质量
$I$转动惯量 (moment of inertia)

与粒子模拟的对比:

  • 粒子只有位置和速度
  • 刚体增加了旋转角度、角速度、力矩和转动惯量
  • 求解方法与粒子完全相同(还是那些 ODE 求解器)

也就是说,第 5 节里辛苦学的那些积分器,在这里能原封不动地复用——只是"状态"从一个向量变成了一个更长的向量。


7 流体模拟 (Fluid Simulation)

基于位置的简单流体方法

核心思想:

  1. 假设水由小刚体球组成
  2. 假设水不可压缩(即密度恒定)
  3. 只要密度在某处发生变化,就通过改变粒子位置来"修正"
  4. 需要知道密度对每个粒子位置的梯度
  5. 更新方法:梯度下降

基于位置的流体模拟

欧拉方法 vs 拉格朗日方法

模拟大量物质有两种不同视角,可以用一个摄影的类比来讲清楚:

方法别名核心思想类比
拉格朗日方法质点法跟随每个粒子的运动摄影师跟随同一只鸟飞过整个路程
欧拉方法网格法在固定网格上观察场的变化摄影师固定不动,拍摄经过某一帧的所有鸟

欧拉 vs 拉格朗日

拉格朗日方法:

  • 模拟每个粒子(质点)的运动
  • 自然追踪物质边界
  • 适合粒子系统、SPH 等

欧拉方法:

  • 在固定网格上观察物理量(密度、速度等)的变化
  • 适合网格化的流体求解(如 Stable Fluids 方法)
  • 不追踪具体物质,关注空间中的场

一句话总结两者的取舍:拉格朗日天然知道"水的表面在哪"(因为粒子在哪就画到哪),但粒子会散乱、难以维持均匀采样;欧拉天然保证网格均匀、便于求导,但要额外做界面追踪(如 level set)才知道自由表面在哪。

光滑粒子流体动力学 (SPH)

SPH (Smoothed Particle Hydrodynamics) 是一种拉格朗日方法:

  • 用粒子表示流体
  • 每个粒子携带质量、密度、速度等属性
  • 通过核函数 (kernel function) 对粒子属性进行光滑插值
  • 求解流体方程(Navier-Stokes 方程的离散形式)

优点:天然处理自由表面,并行性好。

Stable Fluids 方法

Stable Fluids 是一种欧拉方法,由 Jos Stam 提出:

  • 在固定网格上求解流体方程
  • 使用半拉格朗日方法对流
  • 无条件稳定(任意大时间步都不会发散)
  • 广泛用于游戏和视觉效果

物质点方法 (Material Point Method, MPM)

MPM 是一种混合方法,结合了欧拉和拉格朗日两种视角:

阶段方法操作
1. 粒子到网格拉格朗日粒子携带材料属性,转移至网格
2. 网格更新欧拉在网格上进行数值积分
3. 网格到粒子插值将更新后的属性插值回粒子

兔子被融化放进平底锅中

应用:雪、沙、弹性体等复杂材料的模拟。迪士尼《冰雪奇缘》中的雪效果即基于该方法。

(顺带一提,“粒子携带材料 → 搬到网格上积分 → 再搬回粒子”,这个来回的逻辑,正是它同时继承了两种方法的优点:粒子负责记住"这是什么材料"、天然处理拓扑变化,网格负责给出稳定、便于求导的数值环境。)


总结

这一篇覆盖了从"人描述运动"到"计算机推导运动"的完整谱系,可以按两条线索回顾:

按"谁来负责运动"分:

层次方法人负责计算机负责
描述层关键帧动画关键帧与切线插值中间帧
描述层正向运动学关节角度末端位置
描述层逆向运动学末端位置关节角度
数据层动作捕捉 / Blend Shapes真实表演 / 表情基重定向与混合
推导层质点弹簧 / 粒子系统力与约束积分出运动
推导层刚体 / 流体模拟物理规律数值求解

按"数值积分"分(这是本篇的技术核心):

  • 显式欧拉:最简单,一阶精度,容易不稳定
  • 中点法 / 修正欧拉:取平均斜率,明显改善
  • 自适应步长:用误差估计动态调整 $\Delta t$
  • 隐式欧拉:一阶但无条件稳定,代价是要解非线性方程
  • RK4:四阶精度,精度与稳定的最佳平衡点
  • Verlet / 基于位置:用约束和能量耗散换取稳定性

一个贯穿全文的结论:动画里"看得对"往往比"算得准"更重要。无论是 Verlet 主动耗散能量,还是 MPM 在两种视角间来回搬运,都在用物理精确性换取稳定性与可控性。这也解释了为什么图形学偏爱隐式和基于位置的方法,而科学计算偏爱高精度显式方法。

第 12 篇笔记