Palette Director
Palette guidance before the model draws a single pixel
- clip
- palette_image
- positive
- negative
- full_prompt_debug
- palette_report
Say the words "make it red and cream" and a Flux model half-listens, then gives you whatever it feels like. Palette Director tries to pin the vibe down before sampling by handing the model a picture of your palette - the "palette card" - plus a structured prompt suffix that names which color does what. It's guidance, not a guarantee - and it only works if you also load its companion LoRA.
That last part is the headline: on a normal model, this node adds essentially no color control. It prepares conditioning for a palette-trained LoRA. The author tested it against the Flux.2 Klein "Palette Director v1.0" LoRA from Civitai on the flux-2klein-9b-kv-fp8 checkpoint. Without that LoRA loaded, you're feeding a model a format it never learned.
How it works
The node does three concrete things. First, it parses your hex colors and weights and builds the palette-card image - a square (default 1024, from 256 to 2048). The left ~70% is a row of color bars whose widths match your weights; the right ~30% is five stacked role swatches in the fixed order bg, main, human, material, accent. Second, it builds a prompt suffix in the exact format the LoRA was trained on, something like palette_control bg=#111111 main=#2B2B2B ... weights=#111111:34% ... use_palette_roles. Third, it encodes your prompt plus that suffix through the CLIP you hand it, producing real CONDITIONING outputs.
A couple of details worth knowing:
- The
layoutenum (as_written,dark_to_light,light_to_dark,mixed,shuffle) reorders the card's color bars.shuffleis seeded from the palette text, so it's deterministic - it won't change every run. - The suffix only goes into the positive. Your
negative_promptis encoded as-is, no palette chatter. full_prompt_debugshows the exact final prompt;palette_reportis a readable summary. Wire one to a preview when you're debugging.
Inputs that matter
Most fields are self-explanatory, but a few deserve attention:
palette_hex- space-separated hex colors, at least 4 of them. Invalid values like#1234567are rejected outright rather than silently ignored, so a typo fails loudly.weights- relative weights, space-separated, matching the color order. They get normalized internally.role_hex- optional, exactly 5 colors in role order. The tooltip says it plainly: leave it empty and the first 5 palette colors are used.clip- required, and needs to be the Flux.2 Klein CLIP, since that's what the LoRA speaks.- The optional
palette_hex_input/role_hex_input/weights_inputare where you connect the Palette Composer node's outputs, if you don't want to type hex by hand.
Wiring it into a Flux.2 Klein graph
The outputs slot into a standard reference-latent setup. The README's own flow:
palette_image→ VAEEncode → ReferenceLatent attached to your sampling latent (the example attaches it to both positive and negative)positive→ your guider's positive inputnegative→ your guider's negative input- Load the LoRA with a normal LoRA loader (the example uses
LoraLoaderModelOnly) placed before the guider
There's a ready-made example at examples/flux2_palette_director_workflow.json - load it, pick your checkpoint, point the LoRA loader at your download.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/SKBv0/ComfyUI_PaletteDirector
Restart ComfyUI. Dependencies are just numpy, pillow, and torch, all already present. The only download is the LoRA: grab Palette Director v1.0 (Flux.2 Klein) from Civitai and drop it in models/loras. No API calls, no keys.
Where it falls over
The README is refreshingly honest about the failure modes:
- It is not hex-precise. This is pre-generation guidance; the author contrasts it with post-process color transfer tools, which nail exact remapping but can't shape a scene before it exists.
- Prompt color words win fights. A prompt that says "blue jacket" can override a warm red material role.
- The card can leak into the render as blocks, stripes, borders, or UI-like shapes, depending on strength and sampler.
- Object priors push back - skin stays skin-colored, sky stays blue, if the LoRA isn't trained hard enough.
- Role names are hints. The model mixes them up.
- A subtle trap from the README's own comparison: with the card and suffix still connected, LoRA strength 0 is not a clean baseline. If you're A/B testing the LoRA, disconnect the Director entirely.
If output ignores your palette: raise the LoRA strength, strip color words out of the prompt, try a different layout, and accept that some scenes just won't bend. It's an amateur's learning project, but for getting a Flux.2 Klein render to lean into a palette instead of ignoring it, it's a genuinely fun, dependency-light tool.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | — | |
| prompt | STRING | cinematic product photo of a futuristic sneaker on a clean studio plinth | — |
| negative_prompt | STRING | — | |
| palette_hex | STRING | #111111 #2B2B2B #EDEDED #FF3158 #13D8C8 | — |
| role_hex | STRING | Optional 5 colors in role order: bg main human material accent. If empty, the first 5 palette colors are used. | |
| weights | STRING | 0.34 0.24 0.18 0.14 0.10 | — |
| layout | COMBO | as_written | 5 options: as_written, dark_to_light, light_to_dark, mixed, shuffle |
| card_size | INT | 1024256–2048 | — |
| palette_hex_inputopt | STRING | — | |
| role_hex_inputopt | STRING | — | |
| weights_inputopt | STRING | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| palette_image | IMAGE | — |
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |
| full_prompt_debug | STRING | — |
| palette_report | STRING | — |