Composition Layout Generator
The node that decides what kind of shot this is
- layout_json
Take a shot record from the Shot Record Loader, and this node decides how it should be framed. Is this a wide establishing shot, a close-up, an over-the-shoulder two-shot? That's a creative call, and this node is where you make it - but note what it does not do. It produces no boxes, no pixels, no geometry. It produces a plan: which composition, and which subject goes in which slot. The BBox Generator downstream is what turns that plan into actual coordinates.
How the composition gets chosen
The one input that matters is the composition dropdown. It has nine options: auto, plus eight named compositions - centered, rule_of_thirds, left_weighted, right_weighted, closeup, medium, wide, and over_shoulder. The resolution order, straight from the source:
- Your explicit
compositionchoice beats everything. - Otherwise, the shot record's own
compositionfield (if you set one in the JSON). - Otherwise, a deterministic subject-count-aware default: 1 subject →
centered, 2 or more →rule_of_thirds.
That default is worth knowing before it surprises you. A two-subject shot with auto lands in rule_of_thirds, not centered, because centered only has one slot and the second subject would spill onto an overflow grid. The author tuned that default so a balanced two-shot stays balanced.
Once the composition is locked, subjects are assigned to slots in the order they appear in the shot record: the first subject is the primary, everything after it is secondary. The output layout_json is just that - the composition name plus a list of {subject, slot, role} assignments. If you have more subjects than the composition has slots, they still get slot numbers; the BBox Generator handles the overflow placement.
Where the slots come from
This is the nice architectural touch: the eight compositions are pure data, defined in storyboard_layout/data/compositions.json. Each is a set of hand-tuned normalized boxes with an intent label - rule_of_thirds puts the primary on the left third line and the secondary smaller on the right, over_shoulder anchors a foreground figure in a corner while the framed subject sits opposite. Because they're just JSON, you can edit the file to tune any composition without touching a line of Python.
Wiring it up
Shot Record Loader ──► Composition Layout Generator ──► BBox Generator
The shot_json input takes the normalized record from the Shot Record Loader. The layout_json output feeds the BBox Generator. That's the whole chain - five nodes, three of them doing exactly this kind of single, well-defined job.
Gotchas
- One shot at a time. Feed it a shot record containing multiple shots and it errors with "v0.1 processes one shot at a time". No batch mode yet.
- Unknown composition errors happen if you hand the shot record a
compositionfield that isn't one of the eight names. The error message lists the valid ones. - If you keep getting
rule_of_thirdswhen you wanted something else, the shot JSON'scompositionfield might be overriding you - or the default is doing its thing and you haven't touched the dropdown. Set the dropdown explicitly to take control.
It's a small node with a small job, but it's the node that encodes the intent - and in a layout pipeline, intent is the part that's actually hard to get right later.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| shot_json | STRING | — | |
| compositionopt | COMBO | auto | 9 options: auto, centered, rule_of_thirds, left_weighted, right_weighted, closeup, +3 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| layout_json | STRING | — |