Nodes/ComfyUI-MiniMaxH3-Loop/MiniMax H3 Loop Control Video
ComfyUI Node

MiniMax H3 Loop Control Video

Let Blender own your loop geometry

By pxl-pshr·Created 2 days ago·Updated a day ago· 24
MiniMax H3 Loop Control Video
  • images
  • IMAGE
◄fps25►
◄length209►
◄pad_clips1►
◄cycles0►

Text prompts are bad at geometry. Ask H3 for a camera travelling down a looping corridor and you'll get a corridor, and travel, and a loop point that jumps somewhere around second five. Nothing in a text prompt pins a wall to a position across 200 frames.

The fix is the oldest trick in the video book: don't generate the geometry, supply it. MiniMax H3 Loop Control Video is the adapter between a loop you already own - a Blender render, a depth pass - and H3's Fun ControlNet, so H3 restyles it while geometry and timing stay where you put them. In the author's own testing this gave the cleanest loop points of any route.

The actual job

It's a fitter, not a generator. Its description is the whole spec: repeat your loop a whole number of times across the H3 loop at 24 fps, then pad it the same way the latent is padded.

Two things happen in the code. First, length gets snapped to a legal H3 length (17k+5), then the node works out how many copies of your input cycle fit - either cycles if you set it, or, when cycles is 0, the count closest to the input's own speed. Second, it walks every output frame, works out where that frame sits in your input cycle in phase terms, and blends your two nearest input frames by the leftover fraction.

Which is when it's lossy and when it isn't: if your cycle divides the loop exactly - cycles × cycle frames = loop frames - every sample lands on a source frame and nothing is blended. If it doesn't divide, neighbouring control frames get mixed and the geometry softens. The README's numbers: a 34-frame cycle fits length 107 (3 cycles) or 209 (6); a 68-frame cycle fits 209 (3). cycles 0 finds that count for you.

The padding means the output is already the right shape. Don't trim it, don't pad it again - its frame count is the loop plus wrapped context on both sides, ready to plug straight in.

Inputs and outputs

images is one or more whole cycles of a seamless loop. The tooltip has the trap buried in it: frame N+1 == frame 1, not included. Most tools that render a cycling animation hand you the duplicate closing frame. Drop it, or you'll build a one-frame stutter into every cycle.

fps is the frame rate of your clip, not H3's. Default is 25 - if yours is 24 or 30, say so, because this is what the auto-cycle maths uses to match speed. length must equal the length on your H3 workflow, step 17, default 209. pad_clips must equal the MiniMax H3 Loop node's setting. cycles at 0 is the right answer almost always; set it manually when you want the control to run at deliberately the wrong speed for a stylised result.

One output, IMAGE, and it goes into the Apply MiniMax H3 Fun ControlNet node's control video input.

Install and wire it

cd ComfyUI/custom_nodes
git clone https://github.com/pxl-pshr/ComfyUI-MiniMaxH3-Loop

Restart, then download minimax_h3_fun_controlnet_union_pruned_int8_convrot.safetensors into ComfyUI/models/model_patches. That folder matters - not controlnet.

The chain, and the order is not a preference:

model → MiniMax H3 Loop → Apply MiniMax H3 Fun ControlNet → guider/scheduler
control loop → MiniMax H3 Loop Control Video → control_video

MiniMax H3 Loop has to come first, because the ControlNet sizes its control latent from what it sees upstream; reversed, it raises an error. And set views to 1 on MiniMax H3 Loop - views 2 samples a rotated view and the ControlNet only encodes one unrotated control latent, so the pair is explicitly rejected. The pack's own MiniMax-H3-Loop-Control.json has all of this wired, at length 107 with the turbo LoRA in about 4 minutes per loop on a 4090. Point its Load Video node (from VideoHelperSuite) at your own clip.

Prompt the geometry first, then the look. Something like the corridor travelling forward, then what the corridor is made of and how it's lit. The ControlNet is holding the shape; you're only describing texture.

Where it gets fiddly

Soft, mushy geometry. Your cycle doesn't divide the loop and you're getting the blend. Either accept it, or re-render the control at 24 fps with a cycle length that divides the loop frames exactly.

Motion drifts out of sync. Check length and pad_clips - both must match the sampler side - then fps, the one widget here that describes your file instead of the H3 side, and the easiest to leave sitting at its default.

The loop still jumps. Look at the control clip itself, paused at the join. H3 faithfully reproduces a stutter that's already in your control, and a duplicate closing frame is the usual culprit.

A depth pass works as a control source too - Fannovel16's comfyui_controlnet_aux will make one - but that pass then has to loop as cleanly as the thing you're restyling, which is the problem you were trying to avoid. Give it an authored loop when you have one.

Categorymodel/conditioning/minimax

Inputs (5)

NameTypeDefaultDescription
imagesIMAGEOne or more whole cycles of a seamless loop (frame N+1 == frame 1, not included).
fpsFLOAT251–240Frame rate of the input loop.
lengthINT20922–3600Same length as the H3 latent (17k+5).
pad_clipsINT11–8Same pad_clips as MiniMax H3 Loop.
cyclesINT00–256How many times the input loop plays in the H3 loop. 0 picks the count closest to the input's own speed.

Outputs (1)

NameTypeDescription
IMAGEIMAGE—