动画混合篇的 pose 链路产出的是"动画师意图的姿态",落到具体场景里,脚要踩在高低不平的地面上、手要抓不同高度的栏杆——末端位置是场景决定的,骨骼链的姿态是反算出来的,这就是 IK(Inverse Kinematics)。UE 自带三个 IK 节点,数学上分别代表解析解、启发式迭代、贪心迭代三条路线。这篇对比它们的推导、收敛性和适用部位。
问题的统一形式
给定骨骼链 $b_0 \to b_1 \to \dots \to b_n$,末端 $b_n$ 要被拉到目标点 $T$,各骨长度 $l_i$ 固定。链的总长度 $L = \sum l_i$,目标到根的距离 $d$。第一重约束 feasibility:$d > L$ 时链只能尽量伸直指向目标,$d \ll L$ 时链严重折叠——三种算法对不可达情况的处理都是退化路径,真正的差异在可达区间内怎么分配姿态。
TwoBoneIK:解析解,两骨专用
人腿(大腿-小腿-脚)和人臂(上臂-前臂-手)天然是两骨链,TwoBoneIK(FAnimNode_TwoBoneIK)直接求闭式解。把三根点(根、膝、踝)看作三角形,三边已知:$l_1$、$l_2$、$d$。根处的内角 $\theta$ 由余弦定理给出:
$$\cos\theta = \frac{l_1^2 + d^2 - l_2^2}{2 l_1 d}$$
膝的位置在"根到目标连线"与"膝偏移方向"张成的平面内确定,剩余的一个自由度(膝的朝向,左右摆)由 Pole Vector 控制:取根到目标的向量与 Pole 向量的叉积作法线,膝落在这个法线定义的平面上、偏向 Pole 一侧。
解析解的特性是零迭代、零抖动、单帧精确——对游戏是完美的:两骨肢体 IK 的成本就是一个 acos 和两个四元数。代价是它不处理关节限位(膝反折要靠 Pole 向量引导而不是硬约束),且只能两骨——加到第三骨(肩-上臂-前臂-手)就得套两层或换算法。
FABRIK:前后向迭代
FABRIK(Forward And Backward Reaching Inverse Kinematics,FAnimNode_Fabrik)把解析解的思路推广到任意骨数,用两轮几何投影迭代逼近:
- 后向(backward):从末端开始,把 $b_n$ 钉到 $T$;然后向根方向走,每个关节 $b_{i}$ 被移动到"距 $b_{i+1}$ 为 $l_i$、方向保持原相对方向"的位置——链被"拽向"目标但根被拉离了原位;
- 前向(forward):把 $b_0$ 钉回原位置(根固定是常见约束),反向走一遍同样的投影,让链重新生根;
- 每轮两轮投影,$\lVert b_n - T \rVert$ 单调收敛,通常 5–10 轮到达视觉精度。
FABRIK 的收敛质量是三种里最好的(论文证明其误差单调下降),且不碰角速度(全程位置操作,无欧拉角奇异)。工程缺点在关节限位难做:位置空间的投影不保证旋转合法,带限位时收敛变慢且可能卡死。UE 的实现带 bEnableLimits 尝试补偿,效果一般,复杂限位链还是绕行。
CCDIK:贪心逐骨旋转
CCDIK(Cyclic Coordinate Descent,FAnimNode_CCDIK)从末端起,每根骨骼单独旋转让末端靠近目标:
$$\Delta q_i = \text{rotation from } \frac{b_n - b_i}{\lVert b_n - b_i \rVert} \text{ to } \frac{T - b_i}{\lVert T - b_i \rVert}$$
每次只拧一根骨,拧完换下一根,一轮遍历所有骨后重复迭代。单步计算极便宜(叉积求旋转轴),但收敛是近目标慢的典型——末端离目标很近时,每根骨的修正量趋近零但方向互相打架,需要很多轮。优点是限位支持最好(每次只转一根,逐骨夹紧限位很天然),实现也最简单。
选型与组合
按部位和经验收敛速度列个速查:
| 场景 | 推荐 | 理由 |
|---|---|---|
| 腿脚落地(两骨链) | TwoBoneIK | 解析解精确无抖动,Pole Vector 控制膝朝向 |
| 多骨触手/脊椎/尾巴 | FABRIK | 任意骨数收敛快,无角度奇异 |
| 多骨 + 硬关节限位 | CCDIK | 逐骨旋转天然兼容限位 |
| 性能敏感的全局方案 | TwoBoneIK 嵌套 | 解析解成本恒定,迭代类的开销随骨数×轮数涨 |
实践中常见组合:全身 IK 用 FABRIK 跑脊椎-腿链定骨盆和脚,手脚末端再用 TwoBoneIK 精修。注意节点顺序——IK 节点放在 AnimGraph 的后段(在混合之后),否则上层混合会覆盖 IK 的结果。Full Body IK 插件(UE5 新增的 FAnimNode_RigUnit 路径)是另一条路线,基于 Control Rig 的约束求解器,适合同时处理多个末端效应器和接触约束,开销也相应更高。
源码入口
- TwoBoneIK:
AnimNode_TwoBoneIK.cpp,SolveTwoBoneIK就是余弦定理解 + Pole 平面投影,百来行; - FABRIK:
AnimNode_Fabrik.cpp,看EvaluateSkeletalControl_AnyThread里的前后向两轮循环和BoneLengths缓存(Initialize 时一次性算好,Evaluate 里零分配); - CCDIK:
AnimNode_CCDIK.cpp,逐骨旋转循环,注意Precision和MaxIterations的收敛判定; - 共同基类:三者都继承
FAnimNode_SkeletalControlBase,骨骼坐标系转换(component→bone 空间)由基类统一做,自定义 IK 节点也从这里起步。
三种算法的单轮几何直觉: