Nodes/radiance/Shot Grade Router
ComfyUI Node

Shot Grade Router

One JSON table, four grade numbers per shot

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
Shot Grade Router
    • exposure
    • temperature
    • saturation
    • contrast
    • shot_index
    ◄shot_index0►
    ◄grade_table[ { "exposure": 0.0, "temperature": 0, "saturation": 1.0, "contrast": 1.0 }, { "exposure": 0.3, "temperature": -150, "saturation": 0.9, "contrast": 1.1 } ]►

    Sequencing tools have had per-shot grade lookup for decades: the edit decides which shot you're on, the grade database decides what that shot looks like. Shot Grade Router is that idea as a ComfyUI plumbing node - you give it a shot number and a JSON table, it gives you back four numbers you wire into a Grade node.

    It is small. It is also the difference between "grade 40 shots by hand" and "grade 40 shots from one file," which is the entire reason VFX pipelines have this node at all.

    How it works

    Two inputs. shot_index is an INT, and the tooltip says plainly where it's meant to come from: "Current shot index from SceneCutSplit." grade_table is a STRING containing a JSON array - one object per shot, in order, with four keys: exposure, temperature, saturation, contrast. The shipped default gives you two example rows so the shape is obvious:

    [
      {"exposure": 0.0, "temperature": 0, "saturation": 1.0, "contrast": 1.0},
      {"exposure": 0.3, "temperature": -150, "saturation": 0.9, "contrast": 1.1}
    ]
    

    There are no other widgets. No mode, no interpolation, no CSV import. The lookup is positional: shot 0 gets row 0, shot 1 gets row 1.

    Outputs are exposure, temperature, saturation and contrast as FLOATs, plus shot_index passed straight through. That pass-through is deliberate and worth noticing - it means you can chain several of these (one for exposure, one for a look-up table, one for a second stage) without re-deriving the shot number.

    Mechanically it's the simplest family of node in ComfyUI: values in, values out, no pixels touched. The one engine fact that matters is ComfyUI's caching. Because the node's inputs are just a number and a string, it re-evaluates whenever the index or the table changes and does nothing otherwise - so it's cheap to leave in the graph, but you do need something upstream that actually varies the index per clip. That's what the scene-cut tooling in the same pack is for; on its own, this node will happily hand you row 0 forever.

    Wiring it

    Drop it before a Grade node, convert that node's exposure, temperature, saturation and contrast widgets to inputs (right-click → Convert widget to input), and connect the four outputs. Then the grade table becomes a single editable document you keep next to the workflow - and, critically, one you can regenerate from a conform.

    The category is FXTD STUDIOS/Radiance/VFX, so it lives under the VFX folder in the node menu, not under Colour. If you go looking for it in the colour submenu you will not find it, which is a small thing that costs people five minutes.

    Install

    Radiance installs like any pack:

    1. ComfyUI Manager → search Radiance → Install → restart ComfyUI → refresh the browser.
    2. Or manually:
    cd ComfyUI/custom_nodes
    git clone https://github.com/fxtd-studios/radiance.git
    cd radiance
    python -m pip install -r requirements.txt
    

    Windows portable users: use python_embeded\python.exe for that pip line. The pack's requirements are heavy overall (OpenEXR, OpenImageIO, OpenColorIO, diffusers), but you can install Radiance for this node alone and simply never open an HDR graph - nothing here loads a model or downloads a weight.

    Gotchas

    JSON with a trailing comma, or a single object instead of an array, will fail at execution rather than at graph-build time, so a typo shows up as a queue error rather than a red node. Misspell a key - "exposures" - and you'll get the default for that field quietly, because the reader looks up keys individually.

    And a design note worth internalising before you build a shot list around it: the table is fixed, not interpolated. If a shot's look drifts (a sunset going down across a take), four constants won't express it - you'd want to keyframe in a Grade node or split the shot further. This node is for "shot 12 is a half stop brighter than shot 11," which is most of the real work anyway.

    CategoryFXTD STUDIOS/Radiance/VFX

    Inputs (2)

    NameTypeDefaultDescription
    shot_indexINT00–9999Current shot index from SceneCutSplit.
    grade_tableSTRING[ { "exposure": 0.0, "temperature": 0, "saturation": 1.0, "contrast": 1.0 }, { "exposure": 0.3, "temperature": -150, "saturation": 0.9, "contrast": 1.1 } ]JSON array of per-shot grade parameters.

    Outputs (5)

    NameTypeDescription
    exposureFLOAT—
    temperatureFLOAT—
    saturationFLOAT—
    contrastFLOAT—
    shot_indexINT—