H3 RefCap Build View Set
Twenty-four angles of one face, one file
- vae
- views
- orbit
- audio_vae
- orbit_audio
- clip_2
- clip_2_audio
- clip_3
- clip_3_audio
- audio_1
- audio_2
- audio_3
- STRING
The idea
Five front-ish photos of a face get you a very good front-ish character. Ask H3 for a shot over the shoulder and the model has to invent the back of the head from what it saw - which it does, plausibly, and slightly differently every time.
H3 RefCap Build View Set is for the case where you have angles instead of photos. It writes a RefCap with many views of one subject, each tagged with the yaw it was seen from, optionally plus up to three clips (each with a soundtrack) and up to three standalone audio references. The design is lifted from Blender's TURNtable Viewer add-on: a billboard shows whichever frame of a turntable matches the camera's angle. The question the author was asking is whether that trick, applied to H3 references, keeps a character more reliably than a handful of three-quarter shots.
It's a version-3 RefCap - same folder, same h3_refcap header, more keys. And it never stores cached text-encoder rows, on purpose: replay rebuilds them from the pixels, so any subset of views can be replayed natively.
The one design fact that explains the node
H3 cannot look up a reference by viewing angle. Each reference block gets RoPE over time, height and width only; there is no camera input anywhere in the graph. Every block is attended to on every step, and the model copies what it sees rather than reconstructing a head.
So the angle selection has to happen before encoding. That's the entire reason views carry a yaw in metadata, and the entire reason H3 RefCap Replay View Set has a nearest mode. Build View Set is where those yaws get established.
The inputs a beginner actually sets
vae- your video VAE. Each view is encoded exactly as the native reference node would encode it.name- the output file stem.ref_image_size-matchormax, mirroring the native node.matchscales views down to yourwidth×heightarea;maxscales to a 2048 px short edge.matchis the sane default for a 24-view set, because nine views atmaxwill run the text encoder out of memory on a 12 GB card. The pack's own photo-to-RefCap workflow runs atmatchfor exactly that reason.width/height- the size you'll generate at, default 608×352.views- a batch of views of one subject. Order matters; that's what yaws get matched against.view_folder- the better path if you're coming from Blender: a TURNtable image sequence folder, absolute or underComfyUI/input, natural-sorted the same way the add-on sorts it, appended after anything inviews.yaws- one yaw per view in degrees, comma-separated. Leave it empty and you get TURNtable spacing: view i ati × 360/N + frame_offset_degrees.frame_offset_degreesandreverse_directionexist to match however your sequence was rendered. Get the count wrong and it says so.compact- on by default; stores sources as PNGs and redoes the resize at replay, bit-identically, roughly 17× smaller.
Then the version-3 half: orbit (or orbit_folder) is clip 1, with orbit_length - and read that tooltip, because it's the tooltip that bites. It's the length you will render at, default 56, step 17. H3 cuts a reference video to the generation's frame count, so the clip is stored cut to that length. Same for clip_2/clip_3 and their _folder variants, each with an optional *_audio soundtrack. Audio needs audio_vae connected - the node throws rather than silently dropping your soundtrack.
Output is a STRING summary: view count, per-clip frame counts and soundtrack lengths, how many sources were stored as PNG, total reference tokens, file size. It's an output node, so it prints on the node. Watch the token number - see the budget below.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/AEmotionStudio/ComfyUI-RefCap.git
Manager install works too (ComfyUI-RefCap). Nothing to pip install. You need the full H3 set: int8 ref2va DiT, Qwen3-VL-32B encoder, video VAE, and the audio VAE if you're storing sound. And H3's licence excludes the US, EU, UK and South Korea - the pack can't change that.
Budget, and the traps
Reference tokens are the real limit. About 5,000 reference tokens buys one of: 5 views at 1024 px, 9 views at 736 px, or a 56-frame orbit at 544 px. You can store a 24-view turnaround happily - the file just can't use all 24 in one render, and Replay View Set picks up to 9.
JPEG folders aren't the same as JPEG loads. Photos loaded from a folder here go through PIL; Load Image decodes JPEGs through PyAV. They differ by about 0.5/255. PNG sources agree exactly, so use PNG if you're chasing bit-parity against a native reference.
Cold-server video VAE drift. The first video-VAE encode after a server start differs from every later one by a mean of 4e-4, so build sets with clips after the server has run a full H3 graph (one that loaded the text encoder). Images-only sets are unaffected.
Clips need at least five frames, and they're read at 24 fps - the text encoder only sees them at 2 fps. If your clip came out of a 30 fps camera, rescale first or the timing in the reference is wrong.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| vae | VAE | — | |
| name | STRING | character_views | — |
| ref_image_size | COMBO | as MiniMaxH3ReferenceToVideo: 'match' scales views down to the width x height area, 'max' to a 2048 px short edge | |
| width | INT | 60832–16384 | — |
| height | INT | 35232–16384 | — |
| viewsopt | IMAGE | a batch of views of one subject | |
| view_folderopt | STRING | a TURNtable image sequence folder (absolute or under ComfyUI/input), natural-sorted as the Blender add-on sorts it; appended after `views` | |
| yawsopt | STRING | one yaw in degrees per view, comma-separated. Empty: TURNtable spacing, view i at i*360/N + frame_offset_degrees | |
| frame_offset_degreesopt | FLOAT | 0.0-360–360 | — |
| reverse_directionopt | BOOLEAN | false | — |
| orbitopt | IMAGE | clip 1: orbit (or any) video frames at 24 fps, stored as a video reference | |
| orbit_folderopt | STRING | or a folder of clip 1's frames | |
| orbit_lengthopt | INT | 565–3600 | the length you will render at: H3 cuts a reference video to the generation's frame count (applies to every clip) |
| descriptionopt | STRING | — | |
| audio_vaeopt | VAE | the MiniMax H3 audio VAE, needed when any audio is connected | |
| orbit_audioopt | AUDIO | clip 1's soundtrack, stored as its audio latent | |
| clip_2opt | IMAGE | clip 2 frames at 24 fps | |
| clip_2_folderopt | STRING | — | |
| clip_2_audioopt | AUDIO | — | |
| clip_3opt | IMAGE | clip 3 frames at 24 fps | |
| clip_3_folderopt | STRING | — | |
| clip_3_audioopt | AUDIO | — | |
| audio_1opt | AUDIO | standalone audio reference (a voice, music, ambience) | |
| audio_2opt | AUDIO | — | |
| audio_3opt | AUDIO | — | |
| compactopt | BOOLEAN | true | store sources as PNGs and redo the resize at replay (bit-identical, ~17x smaller than the resized floats) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |