π BV LUT Loop Start
The kickoff for a chain of grades
- plan
- initial_image
- resource_provider_1
- resource_provider_2
- resource_provider_3
- resource_provider_4
- resource_provider_5
- resource_provider_6
- resource_provider_7
- resource_provider_8
- resource_provider_9
- resource_provider_10
- resource_provider_11
- resource_provider_12
- resource_provider_13
- resource_provider_14
- resource_provider_15
- resource_provider_16
- resource_provider_17
- resource_provider_18
- resource_provider_19
- resource_provider_20
- resource_provider_21
- resource_provider_22
- resource_provider_23
- resource_provider_24
- resource_provider_25
- resource_provider_26
- resource_provider_27
- resource_provider_28
- resource_provider_29
- resource_provider_30
- resource_provider_31
- resource_provider_32
- resource_provider_33
- resource_provider_34
- resource_provider_35
- resource_provider_36
- resource_provider_37
- resource_provider_38
- resource_provider_39
- resource_provider_40
- flow
- loop_state
Most LUT workflows are one look on one image, and for those you don't need this node. But the interesting case is a sequence of grades - a hero look, then a sky look on top, then a vignette - where each step's mask is computed from the previous step's output. ComfyUI has no native loop construct, so BV Node Pack builds one out of graph expansion, and BV LUT Loop Start is where that loop begins.
It takes a plan (an ordered list of LUT jobs), grabs the starting image, and initializes the loop's accumulator and job counter. Everything after it - the resolver that tells you what the current job is, the Apply LUT that does the work, the Loop End that feeds the result back in - runs in a controlled loop until the plan is exhausted.
How it works
Two inputs do the real work: plan and initial_image. The plan input is deliberately typed as * (anything), because it accepts two different shapes:
- A raw
BV_LUT_PLAN- the output of BV LUT Job chains or BV Regional LUT Plan. - A
BV_REGIONALcontext - in which case the node materializes the LUT plan itself from the regional capabilities plus whatever LUT resource providers you hand it (that's what the 40 optionalresource_provider_1β¦resource_provider_40inputs are for).
Internally it builds the loop state - a BV_LUT_LOOP_STATE holding the plan, the current accumulated image, and a job index - then expands into an invisible BV LUT While Start (Prototype internal) node so the loop can actually re-run in ComfyUI's execution model. You never see that scaffolding; you just see flow and loop_state outputs.
If you hand it an empty plan, it doesn't crash - it substitutes a single Identity LUT job at strength 0, which is a graceful "pass the image through unchanged" fallback.
The inputs and outputs that matter
plan- the job list. From BV Regional LUT Plan if your grades come from regions, or from chained BV LUT Job nodes for a manual list.initial_image- the IMAGE the first job starts from. Usually your decoded latent or the output of the previous processing stage.- Outputs:
flow(a FLOW_CONTROL signal) andloop_state- the latter is what feeds the resolver and eventually Loop End.
That 40-slot provider array looks intimidating but it's just capacity: the regional resource protocol allows up to 40 LUT providers in a graph, and you'll typically wire one or two.
How to install
Part of BV Node Pack, installed as a pack:
cd ComfyUI/custom_nodes
git clone https://github.com/BlackVortexAI/bv_nodepack.git
Restart ComfyUI, hard-refresh the browser (or install via ComfyUI Manager β "BV Node Pack"). No model downloads.
Common issues
- "plan must be a version 1 BV LUT prototype plan" - you fed it something that isn't a valid plan or a regional context. Check that a BV Regional LUT Plan or BV LUT Job actually produced the plan, and that its jobs have
lut,strength, andmask_invertfields. - "requires IMAGE shaped B,H,W,C" -
initial_imageis missing or a non-image type. - Loop runs fewer/more iterations than expected - the loop ends when the job index hits the plan length. If the plan has one job, you get exactly one pass; if you expected stacked looks, you need more jobs in the plan.
For a single look you don't want this at all - BV Apply LUT alone is the right tool. You reach for the loop when later looks genuinely depend on earlier ones.
Inputs (42)
| Name | Type | Default | Description |
|---|---|---|---|
| plan | * | β | |
| initial_image | IMAGE | β | |
| resource_provider_1opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_2opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_3opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_4opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_5opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_6opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_7opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_8opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_9opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_10opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_11opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_12opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_13opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_14opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_15opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_16opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_17opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_18opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_19opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_20opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_21opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_22opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_23opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_24opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_25opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_26opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_27opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_28opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_29opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_30opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_31opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_32opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_33opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_34opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_35opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_36opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_37opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_38opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_39opt | BV_RUNTIME_RESOURCE_PROVIDER | β | |
| resource_provider_40opt | BV_RUNTIME_RESOURCE_PROVIDER | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| flow | FLOW_CONTROL | β |
| loop_state | BV_LUT_LOOP_STATE | β |