时间采样

静态图形学给定场景、几何和光照,任务是算出一帧图像。动画 Animation 把几何扩展到时间维度:每个时刻都有一组几何状态,计算完成后每一帧仍然是一张静止图像,连续播放这些图像才形成运动。

动画最初是交流和叙事手段,评价标准首先是观感和创作意图,而不是每个动作都严格满足物理方程。三维制作仍保留这种取向:关键姿态通常由艺术家决定,物理模拟只负责适合用方程描述的部分,最后还要服务于镜头和风格。

连续运动要被数字系统表示,必须在时间上采样成帧序列。电影常用 24 fps24\,\mathrm{fps},视频常见 30 fps30\,\mathrm{fps},交互内容常以 60 fps60\,\mathrm{fps} 为目标,较高刷新率显示器可以达到 144 Hz144\,\mathrm{Hz} 或更高。相邻画面的时间间隔是

Δt=1fps.\Delta t=\frac1{\mathrm{fps}}.

视觉系统会把快速呈现的相邻画面组织成运动,但“有视觉暂留”并不意味着任意帧率都能保证流畅。若物体在相邻帧之间移动太多,时间采样会产生时间混叠 Temporal Aliasing:高速车轮可能看起来变慢、静止甚至反向。电影帧率与运动快门共同决定观感,有限曝光还会对一帧时间内的辐亮度积分,形成运动模糊 Motion Blur。运动模糊可以压低部分时间高频、减轻突兀的跳变,却不能恢复丢失的运动信息。

应用的要求不同。交互式射击游戏需要低延迟和较高帧率;虚拟现实还要同步双眼视差与头部运动,常见系统需要每只眼睛约 90 fps90\,\mathrm{fps} 的更新能力,否则延迟会被视觉和前庭系统感知为不适。帧率只是采样间隔,是否平滑还取决于运动速度、快门和输入到显示的延迟。

发展脉络

把多幅静止图按顺序播放的想法很早就出现了。洞穴壁画把动物的不同姿态画在相邻位置,转盘通过狭缝让观察者依次看到不同画面,翻页画册则用手指翻动完成同样的时间采样。后来摄影被用于记录奔跑中的马和人体姿态,电影技术最初服务于运动研究,随后才发展为娱乐产业。

完整长度的手绘动画需要每秒绘制许多张画面。主动画师 Key Animator 先确定关键姿态,助手再补出 In-Between。这就是关键帧和补间动画的原型:创作者集中决定少量重要状态,系统或助手负责连接它们。

《白雪公主与七个小矮人》是手绘长篇动画的代表。1963 年的 Sketchpad 用光笔交互定义、旋转、缩放和约束几何,展示了图形内容可以由计算机实时编辑。Ed Catmull 早期的人脸动画展示了低多边形条件下的计算机生成表情;《侏罗纪公园》把计算机生成的恐龙合成进实拍镜头;《玩具总动员》则是第一部完全由计算机生成的长篇动画,它使用早期基于 Reyes 架构的离线 RenderMan,把曲面细分成微多边形后进行着色和可见性采样,与今天实时游戏的三角形管线及路径追踪都需区分。

关键帧补间后来被数字工具部分自动化。Flash 等工具允许创作者指定少量关键帧,由系统在运动不太复杂时生成中间状态,再由制作人员修正细节。后续作品把火焰、风暴、布料、水面和植物细节做得更复杂,但动画仍不必把每个细节都做成严格物理实验。实际制作会在真实感、可控性、计算成本和风格化之间取舍。

关键帧

关键帧动画 Keyframe Animation 把每一帧的状态写成参数向量 qi\mathbf q_i,参数可以包含位置、角度、形变权重和材质控制量。给定相邻关键帧 (ti,qi)(t_i,\mathbf q_i)、(ti+1,qi+1)(t_{i+1},\mathbf q_{i+1}),归一化时间为

α=t−titi+1−ti,0≤α≤1.\alpha=\frac{t-t_i}{t_{i+1}-t_i}, \qquad 0\le\alpha\le1.

位置或标量最简单的线性插值是

q(t)=(1−α)qi+αqi+1.\mathbf q(t) =(1-\alpha)\mathbf q_i+\alpha\mathbf q_{i+1}.

它保证轨迹经过关键帧,位置连续,即 C0C^0 连续;每段内部速度为

dqdt=qi+1−qiti+1−ti.\frac{\mathrm d\mathbf q}{\mathrm dt} =\frac{\mathbf q_{i+1}-\mathbf q_i}{t_{i+1}-t_i}.

如果相邻两段的斜率不同,经过关键帧时速度会瞬间改变,轨迹出现折角。仅仅增加关键帧数量不能自动消除这种速度不连续,需要在关键帧处控制切线。

三次 Hermite Curve 在端点位置之外指定端点速度 mi,mi+1\mathbf m_i,\mathbf m_{i+1}。令 Δt=ti+1−ti\Delta t=t_{i+1}-t_i,则

q(α)=h00(α)qi+h10(α)Δt mi+h01(α)qi+1+h11(α)Δt mi+1,\mathbf q(\alpha) =h_{00}(\alpha)\mathbf q_i +h_{10}(\alpha)\Delta t\,\mathbf m_i +h_{01}(\alpha)\mathbf q_{i+1} +h_{11}(\alpha)\Delta t\,\mathbf m_{i+1},

其中

h00=2α3−3α2+1,h10=α3−2α2+α,h_{00}=2\alpha^3-3\alpha^2+1,\qquad h_{10}=\alpha^3-2\alpha^2+\alpha,

h01=−2α3+3α2,h11=α3−α2.h_{01}=-2\alpha^3+3\alpha^2,\qquad h_{11}=\alpha^3-\alpha^2.

四个基函数分别在端点选择一个位置值或导数,其余端点值和导数为零。因为

dqdt=1Δtdqdα,\frac{\mathrm d\mathbf q}{\mathrm dt} =\frac1{\Delta t}\frac{\mathrm d\mathbf q}{\mathrm d\alpha},

速度项必须乘上 Δt\Delta t,才能让端点的物理速度正好等于 mi\mathbf m_i 或 mi+1\mathbf m_{i+1}。相邻曲线段共享同一个端点速度时,轨迹达到 C1C^1 连续。速度可以由前后关键帧差分估计,也可以由艺术家手动指定来控制节奏。

关键帧插值中位置和速度的连续性

旋转不能把三个角度简单当作普通位置插值。角度有 2π2\pi 周期,例如 350∘350^\circ 到 10∘10^\circ 的短路径是正向 20∘20^\circ,直接线性插值却会走反向 340∘340^\circ。三维旋转可用单位四元数 q=(cos⁡(β/2), nsin⁡(β/2))q=(\cos(\beta/2),\,\mathbf n\sin(\beta/2)) 表示,其中 n\mathbf n 是单位旋转轴,β\beta 是物理旋转角。qq 和 −q-q 表示同一个旋转;若 q0⋅q1<0q_0\cdot q_1<0,先令 q1←−q1q_1\leftarrow-q_1,选择较短路径。两四元数的球面夹角为

θ=arccos⁡ ⁣(clamp⁡(q0⋅q1,−1,1)).\theta=\arccos\!\left(\operatorname{clamp}(q_0\cdot q_1,-1,1)\right).

当 θ\theta 不接近零时,SLERP Spherical Linear Interpolation 为

slerp⁡(q0,q1;α)=sin⁡[(1−α)θ]sin⁡θq0+sin⁡(αθ)sin⁡θq1.\operatorname{slerp}(q_0,q_1;\alpha) = \frac{\sin[(1-\alpha)\theta]}{\sin\theta}q_0 + \frac{\sin(\alpha\theta)}{\sin\theta}q_1.

这个式子可由平面内的正交分解得到:令 q⊥=(q1−q0cos⁡θ)/sin⁡θq_\perp=(q_1-q_0\cos\theta)/\sin\theta,则 q(α)=q0cos⁡(αθ)+q⊥sin⁡(αθ)q(\alpha)=q_0\cos(\alpha\theta)+q_\perp\sin(\alpha\theta)。代入 q⊥q_\perp,用正弦差角公式展开,就得到上面的两端点系数。它始终保持单位长度,并按等角速度走过圆弧;物理旋转角的变化是四元数球面角变化的两倍。四元数必须先归一化;θ\theta 很小时 sin⁡θ\sin\theta 会造成数值不稳定,可以改用线性插值后再归一化。欧拉角需要处理周期分支,并可能遇到万向节锁,因此只适合明确知道参数范围较小的场合。颜色和材质也要按物理含义选择插值空间,sRGB 编码值不应直接当作线性光强插值。

动力学

运动学直接规定位置或关节参数随时间怎样变化;动力学 Dynamics 从力和质量推出运动。牛顿第二定律为

F=ma=mdvdt=md2xdt2.\mathbf F=m\mathbf a =m\frac{\mathrm d\mathbf v}{\mathrm dt} =m\frac{\mathrm d^2\mathbf x}{\mathrm dt^2}.

给定受力模型和初始位置、初始速度,就可以先积分加速度得到速度,再积分速度得到位置。把二阶方程拆成一阶状态方程,令 y=(x,v)\mathbf y=(\mathbf x,\mathbf v),得到

ddt(xv)=(vF(x,v,t)/m).\frac{\mathrm d}{\mathrm dt} \begin{pmatrix} \mathbf x\\ \mathbf v \end{pmatrix} = \begin{pmatrix} \mathbf v\\ \mathbf F(\mathbf x,\mathbf v,t)/m \end{pmatrix}.

状态、力模型和积分器需要分别判断。力模型决定布料、头发或水滴之间的相互作用是否合理;积分器决定连续方程离散后是否稳定、精度如何以及能量怎样变化。碰撞和接触还需要额外的几何约束或事件处理。

以布料为例,把网格顶点当作带质量的质点,每个顶点受到重力、相邻顶点通过弹簧产生的力、接触压力和摩擦力。布料跟随手臂移动不能只靠重力,还需要接触、摩擦和内部拉伸/弯曲约束。穿入身体或两条腿互相穿过是碰撞处理失败的表现。模拟阶段只计算位置和形状,渲染阶段再把几何变成图像;同一组模拟结果可以用不同材质和光照呈现。

衣物接触角色的模拟

图中衣物贴合肩部和躯干,折痕由内部拉伸、弯曲与身体接触共同决定,单独为全部顶点加重力不足以得到这种状态。

流体的自由表面与障碍物

水体在障碍物周围形成波动和自由表面。模拟计算这些空间状态,渲染才让它呈现透明、反射和泡沫等外观;两阶段可以分别改变。

弹簧与阻尼

质点—弹簧系统由一组质点和连接它们的弹簧组成。对端点 a,ba,b,令

d=xa−xb,ℓ=∥d∥,d^=dℓ.\mathbf d=\mathbf x_a-\mathbf x_b,\qquad \ell=\lVert\mathbf d\rVert,\qquad \hat{\mathbf d}=\frac{\mathbf d}{\ell}.

其中 d^\hat{\mathbf d} 从 bb 指向 aa。静止长度为 ℓ0\ell_0、刚度为 ksk_s 的弹簧势能为

Es=12ks(ℓ−ℓ0)2.E_s=\frac12 k_s(\ell-\ell_0)^2.

由 ∂ℓ/∂xa=d^\partial\ell/\partial\mathbf x_a=\hat{\mathbf d},作用在 aa 上的弹簧力为

fa←b=−∂Es∂xa=−ks(ℓ−ℓ0)d^.\mathbf f_{a\leftarrow b} =-\frac{\partial E_s}{\partial\mathbf x_a} =-k_s(\ell-\ell_0)\hat{\mathbf d}.

若 ℓ>ℓ0\ell>\ell_0,该力沿从 aa 指向 bb 的方向,把弹簧拉回;若 ℓ<ℓ0\ell<\ell_0,力改变方向,推动两端分开。作用在 bb 上的力是相反数,弹簧内部不会凭空产生净力。刚度的单位为 N/m\mathrm{N/m},数值越大,给定形变产生的恢复力越大。

零静止长度是特殊的 ℓ0=0\ell_0=0 情况:

fa←b=−ks(xa−xb).\mathbf f_{a\leftarrow b}=-k_s(\mathbf x_a-\mathbf x_b).

它在两点重合时仍为零,避免了归一化方向的退化;普通 ℓ0>0\ell_0>0 弹簧在两点重合时没有唯一恢复方向,代码需要正则化或另选退化方向。

理想无阻尼弹簧会在动能和势能之间不断交换,受到扰动后永久振荡。全局阻尼常写成

fd=−kdv.\mathbf f_d=-k_d\mathbf v.

瞬时功率为

fd⋅v=−kd∥v∥2≤0,\mathbf f_d\cdot\mathbf v=-k_d\lVert\mathbf v\rVert^2\le0,

所以连续系统耗散能量。孤立质点的速度按 e−kdt/me^{-k_dt/m} 衰减,时间常数为 m/kdm/k_d;这通常是渐近停下,离散步长过大时仍可能失稳。

全局阻尼会把整体平移也减速,不能描述弹簧内部的相对耗散。对弹簧两端,先取沿弹簧方向的相对速度

vrel=(va−vb)⋅d^.v_{\rm rel}=(\mathbf v_a-\mathbf v_b)\cdot\hat{\mathbf d}.

内部阻尼力可写成

fd,a=−kdvreld^,fd,b=−fd,a.\mathbf f_{d,a}=-k_dv_{\rm rel}\hat{\mathbf d}, \qquad \mathbf f_{d,b}=-\mathbf f_{d,a}.

点积只保留改变弹簧长度的速度分量。若 bb 绕固定的 aa 做圆周运动,相对速度始终垂直于弹簧方向,内部阻尼应为零;只取相对速度的长度会错误地耗散这种切向运动。完整弹簧单元把恢复力和内部阻尼力相加。弹簧刚度带来的快时间尺度约为 m/ks\sqrt{m/k_s},阻尼时间尺度约为 m/kdm/k_d,稳定步长要同时考虑它们。

布料网格

规则布料网格通常需要三类连接:

  • 结构弹簧 Structural Springs 连接水平和竖直相邻点,抵抗经纬方向的拉伸;
  • 剪切弹簧 Shear Springs 连接方格对角点,抵抗面内剪切;
  • 弯曲弹簧 Bending Springs 跨过一个中间点连接更远的顶点,抵抗面外折叠。

只使用结构弹簧时,方格被沿对角方向拉动可以变成菱形,而边长几乎不变。加一组对角弹簧后,这个方向的剪切会受到恢复力,但网格会产生方向偏置;两个对角方向都加入后,面内抗剪行为才更接近各向同性。即使两个方向的对角线都存在,所有连边仍可能位于同一个平面内,沿网格线折叠时边长不变,因此仍需要跨点的弯曲弹簧。

弯曲弹簧通常比结构弹簧和剪切弹簧弱。真实布料可以绕桌边下垂,不应像刚性薄板一样完全拒绝弯曲;弯曲连接的作用是避免网格沿某条线无代价地折成两层。边界顶点还需要固定约束、碰撞约束和合适的积分步长。

质点—弹簧网格的整体变形

质点—弹簧模型直观,但弹簧刚度和网格拓扑不等于连续材料参数。网格加密会改变有效刚度,直接把 ksk_s 当作材料的 Young 模量并不可靠。有限元法 Finite Element Method,FEM 从连续体的应变能和材料本构出发,将物体离散成单元,在单元内插值位移,再对能量求梯度得到力,材料参数与网格的关系更系统。

Young 模量 描述单轴应力与应变的比例,Poisson 比 描述轴向伸长伴随的横向收缩。汽车碰撞模拟要求受力和损伤能从撞击位置向车身其他部分传递,热量从金属勺尖传到手柄也是一种连续体中的扩散过程。有限元适合这些需要材料参数和传导关系的任务,但建模、组装和求解成本高于质点—弹簧。布料的真实结构还包含纤维、纱线和编织层级,质点—弹簧只是对它的可控近似。

结构弹簧与剪切弹簧分别抵抗轴向拉伸和对角剪切

粒子系统

粒子系统 Particle System 用大量带有位置、速度、寿命等少量属性的个体表示烟尘、火花、喷泉、碎屑、流体或群体。拓扑会不断变化的现象不适合用一张固定网格描述,粒子系统则把个体生成、运动和消亡作为状态的一部分。粒子数量增加通常能提高空间细节,但计算、邻域查询和渲染成本也随之上升。

每个时间步可以按以下顺序处理:

  1. 生成新粒子并设置初始位置、速度和寿命;
  2. 计算重力、风力、阻力、吸引、排斥及粒子间作用;
  3. 用积分器更新速度和位置;
  4. 处理碰撞、约束和粒子间接触;
  5. 删除寿命结束或离开范围的粒子;
  6. 将粒子作为点精灵、网格、体积或隐式表面渲染。

这套流程本身并不决定现象的种类:把相互作用写成水滴的作用,结果可能像水;换成灰尘的阻力和碰撞,结果就会像灰尘。受力模型属于建模,如何从力得到下一时刻状态属于数值求解,两者不能互相替代。

粒子间的长程引力是一个典型例子。令

rij=xj−xi,r=∥rij∥,r^ij=rijr,\mathbf r_{ij}=\mathbf x_j-\mathbf x_i,\qquad r=\lVert\mathbf r_{ij}\rVert,\qquad \hat{\mathbf r}_{ij}=\frac{\mathbf r_{ij}}r,

则粒子 jj 作用在 ii 上的万有引力为

fi←j=Gmimjr2r^ij.\mathbf f_{i\leftarrow j} =G\frac{m_im_j}{r^2}\hat{\mathbf r}_{ij}.

当 rr 很小时平方反比项会产生数值奇点,可以用软化长度 ε\varepsilon:

fi←j=Gmimjrij(∥rij∥2+ε2)3/2.\mathbf f_{i\leftarrow j} =Gm_im_j\frac{\mathbf r_{ij}} {\bigl(\lVert\mathbf r_{ij}\rVert^2+\varepsilon^2\bigr)^{3/2}}.

当 r≫εr\gg\varepsilon 时它接近原公式,r→0r\to0 时力保持有界,代价是极近距离的吸引被削弱。全对交互需要 O(N2)O(N^2) 次查询;短程作用可用网格、空间哈希或邻域列表,长程引力可以用 Barnes–Hut Tree 把足够远的粒子群用总质量和质心近似,但误差和复杂度取决于开角阈值,不能无条件地宣称所有粒子系统都是 O(Nlog⁡N)O(N\log N)。

粒子碰撞、斥力、弹簧连接、摩擦、黏滞力和容器边界都可以成为模型的一部分。星系模拟中的粒子不能只画成数学点,否则在屏幕上不可见,需要按尺度使用点精灵、体积或其他表示。模拟决定粒子位置,渲染决定最终外观,二者仍是两个阶段。

把粒子的一帧更新写成程序,需要把状态更新和最终绘制分开:

1
2
3
4
5
6
7
8
对每个时间步:
产生新粒子,设置状态和寿命
为全部粒子建立邻域结构
从当前状态计算力
用积分器更新位置与速度
求解碰撞和约束,更新寿命
删除失效粒子
把当前粒子状态交给渲染器

群集

Flocking 把群体看成大量有局部感知规则的个体。经典规则包括:

  • 分离 Separation/Repulsion:与过近邻居保持距离,避免重叠;
  • 对齐 Alignment:趋向邻域平均速度或朝向;
  • 聚合 Cohesion/Attraction:趋向邻域的中心或保持群体联系。

个体通常只读取有限邻域的位置和速度,再按权重组合出加速度或速度修正。若邻域查询使用空间结构,成本可以接近线性;若每个个体都检查全部个体,仍然是 O(N2)O(N^2)。这些规则是行为模型,不是基本物理定律;半径、权重和最大速度需要随场景尺度调节。鸟群、鱼群、人群乃至分子示意都可以用“个体—局部规则—群体涌现”的框架描述,但个体的状态和碰撞规则会不同。

Flocking 由局部规则形成群体运动

骨架运动

角色骨架是由关节和骨段组成的层级树。铰链关节 Hinge Joint 只允许绕一根轴旋转;球窝关节 Ball-and-Socket Joint 允许绕多个方向旋转;滑动关节 Prismatic Joint 允许沿给定轴平移。关节类型先规定自由度,之后的动画和反解都只能在这些自由度上操作。

正向运动学 Forward Kinematics,FK 从关节参数计算所有关节和末端的世界变换。若父子变换采用列向量和左乘世界变换的约定,关节 jj 的全局变换可写为

Tjworld=TrootT1⋯Tj.T_j^{\rm world} =T_{\rm root}T_1\cdots T_j.

乘积只包含根节点到 jj 的祖先链,每个 TkT_k 都是相对父节点的局部变换,不包含其他旁支;父关节的运动会传播给全部后代。

在二维平面中,若机械臂有 mm 段,长度为 ℓk\ell_k,第 kk 个关节相对于父关节的角度为 θk\theta_k,累计世界朝向为

ϕk=∑j=1kθj.\phi_k=\sum_{j=1}^{k}\theta_j.

末端位置为

x(θ)=∑k=1mℓkcos⁡ϕk,y(θ)=∑k=1mℓksin⁡ϕk.x(\boldsymbol\theta)=\sum_{k=1}^{m}\ell_k\cos\phi_k, \qquad y(\boldsymbol\theta)=\sum_{k=1}^{m}\ell_k\sin\phi_k.

给定每个关节参数,末端位置是确定的;FK 的问题在于动画师通常想拖动手或脚,而不想逐个调角度。

逆运动学

逆运动学 Inverse Kinematics,IK 把末端目标位置作为输入,反求能实现该目标的关节参数。两段平面机械臂的长度为 ℓ1,ℓ2\ell_1,\ell_2,根部到目标 (x,y)(x,y) 的距离满足

r2=x2+y2.r^2=x^2+y^2.

若 θ2\theta_2 是第二段相对第一段的关节角,余弦定理给出

r2=ℓ12+ℓ22+2ℓ1ℓ2cos⁡θ2,r^2=\ell_1^2+\ell_2^2+2\ell_1\ell_2\cos\theta_2,

因此

cos⁡θ2=r2−ℓ12−ℓ222ℓ1ℓ2.\cos\theta_2 =\frac{r^2-\ell_1^2-\ell_2^2}{2\ell_1\ell_2}.

实数解要求

∣ℓ1−ℓ2∣≤r≤ℓ1+ℓ2.|\ell_1-\ell_2|\le r\le \ell_1+\ell_2.

上界是完全伸直时的最大距离,下界是两段折叠后的最小距离。若 ℓ1=ℓ2\ell_1=\ell_2,内边界退化到根部。只要右侧在 [−1,1][-1,1] 内,sin⁡θ2\sin\theta_2 的正负通常对应肘部向上和向下两组解。选定 θ2\theta_2 后,第一段角度可写成

θ1=atan2⁡(y,x)−atan2⁡(ℓ2sin⁡θ2, ℓ1+ℓ2cos⁡θ2).\theta_1=\operatorname{atan2}(y,x) -\operatorname{atan2}\left( \ell_2\sin\theta_2,\, \ell_1+\ell_2\cos\theta_2 \right).

因此 IK 天然会有无解、多解和奇异姿态。目标落在环域外时无解;肘部向上/向下或冗余关节会产生多解;机械臂接近完全伸直时,末端在某些方向上很难移动,Jacobian 变得病态。

复杂骨架通常把 IK 写成优化问题。令末端映射为 f(θ)f(\boldsymbol\theta),目标为 p∗\mathbf p^*,误差能量为

E(θ)=12∥f(θ)−p∗∥2.E(\boldsymbol\theta) =\frac12\lVert f(\boldsymbol\theta)-\mathbf p^*\rVert^2.

记 e=f(θ)−p∗\mathbf e=f(\boldsymbol\theta)-\mathbf p^*,Jacobian 为

J=∂f∂θ.J=\frac{\partial f}{\partial\boldsymbol\theta}.

链式法则给出

∇θE=JTe.\nabla_{\boldsymbol\theta}E=J^T\mathbf e.

最简单的梯度下降为

θk+1=θk−ηJTe.\boldsymbol\theta_{k+1} =\boldsymbol\theta_k-\eta J^T\mathbf e.

局部线性化 f(θ+Δθ)≈f(θ)+JΔθf(\boldsymbol\theta+\Delta\boldsymbol\theta)\approx f(\boldsymbol\theta)+J\Delta\boldsymbol\theta 后,Gauss–Newton 方法求解

JTJΔθ=−JTe.J^TJ\Delta\boldsymbol\theta=-J^T\mathbf e.

接近奇异姿态时 JTJJ^TJ 可能病态,Damped Least Squares 使用

(JTJ+λI)Δθ=−JTe.(J^TJ+\lambda I)\Delta\boldsymbol\theta=-J^T\mathbf e.

λ>0\lambda>0 抬高小特征值,使奇异方向的步长受控;λ\lambda 较小时接近 Gauss–Newton,较大时接近小步长梯度下降。关节限位、脚底接触、姿态偏好和避障可以作为约束或附加能量加入,避免求解器只追求末端位置而产生不合适的全身姿态。

两段机械臂的多解、可达区域和末端映射

绑定与蒙皮

Rigging 把角色网格、骨架、控制器和运动约束组织成可制作的系统;蒙皮 Skinning 决定骨架运动如何影响网格顶点。绑定姿态记录网格与骨架的初始相对关系,控制器为动画师提供比直接编辑每个关节角更适合创作的操作。

线性混合蒙皮 Linear Blend Skinning,LBS 为每个顶点 ii 分配关节权重 wijw_{ij}:

wij≥0,∑jwij=1.w_{ij}\ge0,\qquad \sum_jw_{ij}=1.

设 xˉi\bar{\mathbf x}_i 位于绑定姿态的模型空间,BjB_j 把关节 jj 的局部坐标变换到绑定姿态模型空间,TjT_j 把它变换到当前模型空间,则

xˉi′=∑jwijTjBj−1xˉi.\bar{\mathbf x}_i' =\sum_jw_{ij}T_jB_j^{-1}\bar{\mathbf x}_i.

Bj−1B_j^{-1} 先把绑定顶点带入关节局部坐标,TjT_j 再把它带回当前模型空间,最后按权重混合。实际顶点通常只保留少量非零权重,便于 GPU 使用固定大小的属性数组。

加权后的矩阵一般不再是严格的旋转矩阵。两个相反旋转的加权平均会让截面收缩,形成 Candy-Wrapper Artifact;双四元数蒙皮、校正形状或数据驱动修正可以减轻这种扭曲,但不能取代合理的权重与关节设计。权重突变会产生折痕,权重绘制、平滑以及控制器范围都是绑定阶段的重要工作。

骨骼、关节控制器与蒙皮网格的关系

形状基

骨骼适合整体刚性运动,脸颊、眼睑、嘴角和舌头等局部软组织可用形状基 Blend Shapes 控制。设基准网格为 x0\mathbf x_0,第 kk 个目标形状相对基准的顶点位移为 Δxk\Delta\mathbf x_k,则

x=x0+∑kwkΔxk.\mathbf x=\mathbf x_0+\sum_k w_k\Delta\mathbf x_k.

wkw_k 是无量纲权重,通常在制作约定下限制在 [0,1][0,1],也可以通过校正规则允许更复杂的组合。它直接在线性顶点位移空间混合不同表情,不改变网格拓扑。骨骼可以负责头部转动和下颌的整体运动,Blend Shapes 负责面部局部形变;两者可以叠加。

形状基的组合需要遮罩和约束,否则多个表情同时激活可能产生不符合制作意图的嘴角穿插、眼睑穿透等结果。它与关键帧插值的共同点是都在一组参数之间取连续状态,但插值对象从关节参数换成了顶点位移基。

Blend Shapes 用形状基和权重组合表情

动作捕捉

动作捕捉 Motion Capture,MoCap 从真人演员获得离散运动数据,再把这些数据拟合或优化到虚拟角色骨架。光学系统给演员贴反光标记或穿带标记的服装,用多台已标定相机观察标记;每个二维像点对应一条空间射线,多台相机的射线通过最小二乘交会得到标记的三维位置。

标定需要内参 Intrinsics,如焦距与主点位置,以及外参 Extrinsics,即相机在场景中的位置和姿态;它们让二维像点能够转换成同一世界坐标系中的射线。至少两个有效视角才能交会一个三维点,实际系统会使用更多相机提供遮挡冗余。一个快速动作捕捉系统可以使用八台以上相机、约 240 Hz240\,\mathrm{Hz} 的采样率,这些是设备配置示例,不是所有 MoCap 方法的固定门槛。演员转身、手臂遮挡躯干或标记互相遮挡时,需要依靠剩余视角、轨迹连续性和后处理补齐缺帧。

光学被动标记把红外光反射回相机,主动光学标记自行发光,但二者都要求有效视线,身体遮挡仍会导致丢失。磁性或其他非光学方案可不依赖光学视线,却会受场干扰和设备条件限制。惯性方案用 IMU 测角速度和加速度,长期积分可能漂移;机械方案直接测量关节或装置的相对运动,通常会限制演员动作。

捕捉完成后还要做标记命名、轨迹滤波、缺帧修复、骨架拟合和 动作重定向 Retargeting。源演员和目标角色的骨骼比例不同,不能只复制坐标,还要保持脚底接触、关节限位和动作风格。真人动作也未必符合卡通角色的夸张要求,捕捉数据通常需要人工修整。

《阿凡达》的虚拟角色展示了身体和面部捕捉结合的制作方式。面部捕捉用密集标记、深度相机或表情基记录微小的眼睑、嘴角和眼球运动。几何、材质和时序稍有不协调,观察者就可能感觉角色落入恐怖谷 Uncanny Valley;它描述的是接近真人但仍有不自然之处造成的不适,不是对某一种技术或人工智能的必然判断。

动作捕捉从标记观测恢复骨架运动

制作流程

一部动画长片通常先从创意、剧本、分镜和动态分镜(animatic)开始,再进入制作。前期确定镜头内容和美术方向;制作阶段包括 layout、建模、纹理、绑定与设置、关键帧或捕捉动画、布料/毛发/流体等视觉特效、灯光和渲染;后期进行合成、二维效果、调色、立体版本和最终输出。

视觉特效 Visual Effects,VFX 包括计算机生成内容与后期图像合成;制作流程中的 fx 常特指布料、烟、火和流体等效果。拍摄现场的 Special Effects 则指实体装置、爆破等现场效果,不能把两者简单等同。渲染完成的三维图像还可以与绿幕实拍素材、背景和二维图形合成。模型与纹理、绑定、动画、灯光和特效之间需要反复迭代,最终成本主要来自制作人力和渲染机时,后者常由 render farm 承担。

动画长片的制作流程

三排分别组织前期、制作和后期:故事与分镜先确定镜头,模型、纹理和绑定为动画提供资产,灯光与特效参与渲染,输出再进入合成和调色。图中的并列工序还说明它们要反复协作,不能视为一次走完就不再修改的严格流水线。