Nodes/PerfectLab Studio/PerfectLab Studio
ComfyUI Node

PerfectLab Studio

One node that plans a whole photoshoot, and why its output is a list

By perfectmodelslab·Created 9 months ago·Updated 8 days ago· 23
PerfectLab Studio
    • PROMPT
    • NEGATIVE
    • WIDTH
    • HEIGHT
    • SEED
    • META
    ◄node_data{}►
    ◄modesession►
    ◄seed0►
    ◄variations1►

    First thing to know: this pack ships exactly one node. The repo has nine Python modules and a web/ folder of panel JavaScript, but NODE_CLASS_MAPPINGS exposes PerfectLabStudio and nothing else. Those other modules are the engine the panel calls into - so if you install this and see one node in the menu, nothing is broken.

    What it actually does

    PerfectLab Studio is a photoshoot planner wearing a node's clothes. You pick a person, an outfit, a place, a light setup, a camera and a mood from libraries that ship with preview tiles, and the node emits the prompt, size, seed and metadata line for every frame. It's what you reach for when you want twenty coherent portrait frames out of one queue run instead of twenty hand-typed prompts.

    The libraries are the point, not a gimmick. 625 values across persona, look, scene, light, style, camera, pose and expression, each carrying a preview tile rendered through a real graph on the same face - so you can see what "butterfly light" or "cold girl makeup" does before committing it to a batch. That's the community's most-repeated prompting lesson made clickable: name a concrete physical fact, don't vibe at the encoder.

    How it works under the hood

    There's no API and no key. The panel is a JavaScript widget, and everything you click is serialized into node_data, a JSON string (schema v2) that the Python side parses and feeds to the composers. The panel is a skin over a session engine.

    That engine is where the good bits live. With a multi-select field active, the node doesn't cram every value into one prompt - it walks the list, handing each shot one value in order, so picks rotate across the session. Dramaturgy arcs add an energy curve: a quiet point renders once and pulls a wider crop, a climax gets the full take stack and a tighter frame. {a|b|c} choices and __wildcard__ files resolve per shot from that shot's seed, using an FNV-1a hash the JavaScript mirrors - which is why the panel's preview matches what actually renders. That brace syntax is old A1111 wildcard grammar most people arriving after 2024 never learned, and still the cheapest way to get variety without training anything.

    Inputs and outputs

    node_data is the hidden input carrying the whole panel state - you never type in it. You set mode (single shot or session), seed, and variations, which applies only in single-shot mode and controls how many prompt variations you get. Session length is not variations; it comes from the shot count you set in the panel.

    Outputs are all lists: PROMPT, NEGATIVE, WIDTH, HEIGHT, SEED, META. Wire PROMPT into a CLIP Text Encode positive, NEGATIVE into the negative, WIDTH/HEIGHT into Empty Latent Image, SEED into the KSampler. META is a JSON recipe per shot - framing tier, seed, takes - and doubles as caption material if you're building a dataset.

    ComfyUI iterates list outputs downstream, which is the whole trick: six shots means six frames in one queue run, each with its own size, seed and prompt. The prompt-style switch retargets wording and token budget per family - natural language for Z-Image (400 tokens), Flux (512) and Qwen-Image (1024), comma tags chunked at 75 for SDXL. The linter flags token overflow, unbalanced braces, duplicates and missing wildcard files before you hit queue. On distilled models at CFG 1 the negative is mathematically inert, so leave NEGATIVE unwired there; at CFG 3.5–7 on SDXL or Flux Dev it still earns its place.

    Install

    ComfyUI Manager, search PerfectLab, install, restart. Or by hand:

    cd ComfyUI/custom_nodes
    git clone https://github.com/perfectmodelslab/ComfyUI-PerfectLab.git PerfectLab
    

    Then restart ComfyUI. No Python dependencies - pyproject.toml declares an empty dependencies list and there's no requirements.txt, so nothing gets pip-installed and nothing can conflict with the environment you already built. Rare enough in this ecosystem to be worth saying out loud. Preview tiles are files in web/guide/items/; lose those and the panel loads with 404s where the thumbnails should be.

    The repo bundles workflows/perfectlab_base_workflow.json, wired end to end with a demo shoot already picked. Load it, swap the model names in the three loader nodes for yours, press START SHOOT.

    Where people get burned

    A panel that doesn't show up after install or update is almost always the browser - Ctrl+F5. A missing node in the menu is a restart.

    An empty prompt means you picked nothing in persona or look; the node composes from your picks, it doesn't invent a subject. If the text reads wrong for your checkpoint, you're in the wrong style mode - toggle natural/tags.

    Your custom libraries, presets, wildcards and arcs live in the ComfyUI user folder, not the node folder, so they survive updates. The pack ships its own write endpoint because some ComfyUI builds serve the stock userdata routes read-only and quietly 405'd the POSTs, killing saved custom entries. If you see PerfectLab: userdata routes not registered in the console, custom entries are what'll misbehave.

    Last, the honest caveat: a prompt cannot lock a face. The persona fields, the LoRA trigger line and per-shot seeds keep the description consistent across a session. Same person across sessions and outfits still means a character LoRA in that trigger line - this node gives you a consistent casting sheet, not identity.

    CategoryPerfectLab

    Inputs (4)

    NameTypeDefaultDescription
    node_dataSTRING{}—
    modeCOMBOsession2 options: single shot, session
    seedINT00–18446744073709550000—
    variationsINT11–100Single-shot mode: how many prompt variations to produce.

    Outputs (6)

    NameTypeDescription
    PROMPTSTRING—
    NEGATIVESTRING—
    WIDTHINT—
    HEIGHTINT—
    SEEDINT—
    METASTRING—