StoryMakerTwoPortraitNode
Two Characters in One Frame Without Them Merging
- image1
- mask_image1
- image2
- mask_image2
- IMAGE
Putting two specific characters in the same frame is the hard mode of character consistency. Getting one person to look like themselves is solved well enough; getting two people to each stay themselves - without them swapping features or fusing into a hybrid - is where most pipelines quietly fall over. StoryMakerTwoPortraitNode is one of the few nodes that tries it directly, and it comes from a research project that made two-character scenes a headline feature rather than an afterthought.
It's the third node in the tanglaoya321/ComfyUI-StoryMaker pack, a thin wrapper around RedAIGC's StoryMaker model (arXiv 2409.12576). Same shared pipeline as its siblings, so install is identical - see the single-portrait node page for the full rundown: ComfyUI Manager or git clone, a pip install diffusers transformers accelerate insightface opencv-python, and a first run that downloads the ~6.5 GB YamerMIX SDXL base plus the CLIP encoder from HuggingFace.
How it keeps two identities straight
Where the single-portrait node runs one face through the adapter, this one runs two. It detects the largest face in each of your two reference images with InsightFace's buffalo_l, produces an ArcFace embedding for both, and passes two identity channels plus two masks into the pipeline. Each character gets their own embedding slot, and the two face-region masks tell the model where each identity should live in the final composition. The prompt then writes the scene: "a person is doing X while another person is doing Y."
That dual-channel design is the whole trick, and it's why this node is worth knowing about at all. Standard IP-Adapter setups juggling one reference at a time tend to blend identities when asked for two people; giving each character a dedicated embedding and mask is precisely the kind of scaffolding the community spent 2025 and 2026 asking for. It doesn't always succeed - identity bleed is still a real failure mode, and the two faces can drift toward each other if the masks overlap or the composition is too tight - but it's one of the few turnkey local options for a two-character scene.
The inputs
Six inputs, and four of them are pairs:
- image1 / mask_image1 and image2 / mask_image2 - one clear reference portrait and one face-region mask per character. The largest face in each reference is what actually gets used, so crop out clutter.
- prompt - describe the scene and what each person is doing. The prompt is your main lever for separating them ("…wearing a red jacket" vs "…wearing a blue dress" does a lot of work).
- negative_prompt and seed - standard fare.
The output is one IMAGE at the fixed 1280×960 render size (25 steps, CFG 7.5, hardcoded - no resolution or sampler controls). Save Image or Preview Image is the whole wiring.
The caveats, in order of how much they'll hurt
Same pack-wide realities: every generation tears down and reloads the full model, so consecutive runs are minutes apart; it wants ~10 GB of VRAM; the output skips the usual VAE denormalize, so a dark or clamped render is the known quirk, not your mistake; and InsightFace's model weights are non-commercial research only. You also still need to place mask.bin at StoryMaker/checkpoints/ by hand.
The two-character-specific warnings: keep the two face masks separated, keep the faces reasonably large and well-lit in the references, and budget for re-rolls - the first seed that gives you character A right will often give you character B wrong, and you'll be trading until both click. It's fiddly, but it's the fiddliness of an unsolved problem, not a broken node. And one frame is a snapshot, not a story: render several scenes with the same two references to actually get the "story" the pack's name promises.
Also worth knowing: the pack is a port of a September 2024 research model and hasn't been updated since October 2024. On an anime style it holds up fine; if your project is photorealistic or Flux-era, this SDXL-based wrapper is the wrong tool and you'd be better served by the modern edit-model stack. Within its lane, though, it's a rare capability - two characters, both recognizable, sharing a frame.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image1 | IMAGE | — | |
| mask_image1 | IMAGE | — | |
| image2 | IMAGE | — | |
| mask_image2 | IMAGE | — | |
| prompt | STRING | — | |
| negative_prompt | STRING | — | |
| seed | INT | 00–18446744073709550000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |