Motion Matching
September 9, 2024About 3 min
Motion Matching
Motion Matching is a simple idea, that helps us reason about movement description and control.
It’s also a new type of animation system, with three advantages:
- High quality
- Controllable responsiveness
- Minimal manual work
播放动画
一段播放动画的代码:
// start
if (!walking && wantToWalk)
{
PlayAnim(StartAnim);
walking = true;
}
// walk loop
if (IsPlaying(StartAnim) && IsAtEndOfAnim())
{
PlayAnim(WalkLoopAnim);
}
// stop
if (walking && !wantToWalk)
{
PlayAnim(StopAnim);
walking = false;
}
同样可以使用状态机,可视化:
但如果动画过多就会出现下图:
当然还有混合树的情况播放动画:
if (speed > 3.0f)
{
PlayAnim(RunAnim);
}
else if (speed > 0.0f)
{
PlayAnim(WalkAnim);
}
else
{
PlayAnim(IdleAnim);
}
同样也可以使用可视化工具来处理:
多个参数控制动画
如果有多个数据都会影响着动画的播放,就是需要配表来控制标准选择动画,然后实时传递值给动画控制器。这个逻辑就是动画蓝图的功能。
改变固定动画播放路径
选择下一个动画
Reinforcement Learning Based Character Locomotion in Hitman: Absolution
Motion Fields for Interactive Character Animation
Motion Fields 性能消耗非常大,这里只使用了跳转到其他动画的任何一帧。
选择正确的开始和结束时间
- 姿势匹配
- 速度匹配
- 精确的末端位置匹配
原理简介
核心逻辑:每一帧都去寻找最合适的动画,然后跳转播放。
Mocap
先做动作捕捉
Code
下面是每帧计算匹配的简单代码:
int m_CurrentAnimIndex;
int m_CurrentAnimTime;
void AmoUpdate(Goal goal, float dt)
{
m_CurrentAnimTime += dt;
Pose currentPose = EValuateLerpedPoseFromData(m_CurrentAnimIndex, m_CurrentAnimTime);
float bestCost = 1000000;
Pose bestPose;
// loop on all mocap
for (int i = 0; i < m_Poses.Size(); i++)
{
Pose candidatePose = m_Poses[i];
// every candidate jumping point has a cost
float thisCost = ComputeCost(currentPose, candidatePose, goal);
if (thisCost < bestCost)
{
// remember the best candidate
bestCost = thisCost;
bestPose = candidatePose;
}
}
bool theWinnerIsAtTheSameLocation = m_CurrentAnimIndex == bestPose.m_AnimIndex && fabs(m_CurrentAnimTime - bestPose.m_AnimTime) < 0.2f;
if(!theWinnerIsAtTheSmaeLocation)
{
// blend to the winning location
m_CurrentAnimIndex = bestPose.m_AnimIndex;
m_CurrentAnimTime = bestPose.m_AnimTime;
PlayAnimStartingAtTime(m_CurrentAnimIndex, m_CurrentAnimTime, 0.25f);
}
}
Trick 1: Posematch only a few bones
- Local velocity
- Feet positions
- Feet velocities
- Weapon position
Trick 2: Just check where a piece of animation brings you if you play it
动画的目标,部分代码:
class TrajectoryPoint
{
Vector3 m_Position;
float m_Sight;
float m_TimeDelay;
};
// desired goal, sent by gameplay each frame
class Goal
{
Array<TrajectoryPoint> m_DesiredTrajectory;
Stance m_DesiredStance;
// ...
};
计算调整到新的姿势的花销的代码:
float ComputeCost(Pose currentPose, Pose candidatePose, Goal goal)
{
float cost = 0.0f;
// how much the candidate jumping position matches the current situation
cost += ComputeCurrentCost(currentPose, candidatePose);
// this is our responsivity slider
static float reponsivity = 1.0f;
// how much the candidate piece of motion matches the desired trajectory
cost += responsivity * ComputeFutureCost(candidatePose, goal);
return cost;
}
Match more things
- Future Stance Matching
- Elegantly find transitions when they exist
Optimizations
- LOD
- KD-Tree
- Motion Shaders
Trajectory Simulation Choices
- Displacement from Animation?
- Displacement from Simulation? 更可控,可预测
Workflow
- Mocap is tweaked, imported, and marked up
- At runtime Gameplay makes a request(desired trajectory and event constraints)
- The animation system continuously finds the best piece of data to play
- We modify the result to precisely match gameplay and environment
Procedural Touchups
Orientation corrections
- Let the animation decide rotation
- Correctt to match future desired position
- Orientation to match future desired orientation
Sliding Prevention
Lock the toe when it doesn’t move too much in the main animation
Slope Warping
- Carefully tweak ground smoothing
- Smoothly pull the hips down
- Prefer smoothness over absolute penetration prevention
- Don’t break the pose: Never hyper-extend the knee
Slope Animations
Slope anims are automatically chosen by 3D trajectory matching
IK only compensate for what is missing from the anim
Spine Pitch Bending
Keep whole upper body in sync
Reference
- https://gdcvault.com/play/1023280/Motion-Matching-and-The-Road
- https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc2016/Presentations/Clavet_Simon_MotionMatching.pdf
- https://research.cs.wisc.edu/graphics/Papers/Gleicher/Mocap/mograph.pdf
- https://github.com/JLPM22/MotionMatching
- https://zhuanlan.zhihu.com/p/50141261