Face Performance Rig Apply Deltas
Layer performance motion onto your neutral rig without wrecking its identity
- retargeted_frames_json
- summary
The payoff stage of the MKRShift face-rig lane. MKRFacePerformanceRigBuildNeutral gives you the calm, identity-bearing face; MKRFacePerformanceRigApplyDeltas is what pushes a performance onto it. It takes a neutral rig and a stream of motion frames, applies the jaw, lip and blink deltas, and returns retargeted landmark frames - motion layered on top of identity, not replacing it.
This is retargeting in the good sense: the output keeps the rig's base geometry and expresses the motion through it, rather than just pasting raw tracker values onto a different face. If you've built the neutral rig, this is the node that makes it perform.
How it works
Two JSON inputs, one concept:
neutral_rig_json- the object fromMKRFacePerformanceRigBuildNeutral(or anything compatible). This carries the identity geometry and theidentity_mode.motion_frames_json- the performance. Typical fields per the author's docs:jaw_open,lip_open,lip_wide,blink_l,blink_r,intensity, andsmoothing. That last one is nice: per-framesmoothingvalues override the config default when present, so you can spot-smooth a rough section without rebuilding anything.
The retargeter (lib/face_performance/face_rig_retarget.py) computes deltas from the motion frames and applies them onto the neutral rig's landmark set, producing per-frame landmarks, landmarks_2d, and the resolved motion payload. settings_json overrides any FaceRigRetargetConfig field; {} to start.
Outputs: retargeted_frames_json (the landmark frames - wire these to whatever renders or consumes landmarks) and summary (a string reporting frame count and the identity mode it was applied in). The identity mode matters because it tells you whether you're retargeting onto a canonical rig or a reference-built one - and that's baked into how the deltas are interpreted.
The pairing you'll actually use
This node assumes neutral_rig_json came from MKRFacePerformanceRigBuildNeutral, and honestly that's the workflow to build: neutral rig → (optionally) MKRFacePerformancePoseMerge for the merged pose stream → MKRFacePerformanceRigApplyDeltas for the retargeted output. The validator checks that neutral_rig_json is a JSON object and motion_frames_json is a JSON array, so getting the two roles backwards fails fast with a readable error.
Installing and caveats
Standard pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart ComfyUI, or ComfyUI Manager search "MKRShift_Nodes". Pure Python, no new deps.
The straight talk: this is a component for people moving structured face data around - riggers, retarget pipelines, experimental setups - not a plug-and-play animation tool. There's no community signal for it yet (the pack is young), no presets, and the tuning surface is the config class in the source. But if you're in that world, the "preserve identity, layer motion" split between this node and its neutral-rig sibling is a genuinely clean way to think about the problem - and the output is plain JSON, which is exactly as portable as you want retargeted landmarks to be.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| neutral_rig_json | STRING | {} | — |
| motion_frames_json | STRING | [] | — |
| settings_json | STRING | {} | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| retargeted_frames_json | STRING | — |
| summary | STRING | — |