OminiControl Spatial
FLUX Structure Control Without a ControlNet
- ref_image
- image
OminiControl Spatial is this pack's ControlNet-adjacent node: it drives FLUX generation from the structure of a reference image instead of its content. One dropdown - canny, depth, coloring, or deblurring - and the node does the preprocessing and the guided sampling itself. It's the "OminiControl" in the name doing its universal-control thing: the same tiny-LoRA mechanism that preserves subject identity can also steer composition, because both are just ways of feeding condition tokens into the FLUX transformer.
It's not a replacement for a full ControlNet stack - it's simpler and more opinionated than that. You get four modes, no strength dial, no start/end step, and a fixed 512×512 output. What you get instead is zero preprocessing nodes, zero extra packages, and results in 8 schnell steps. For a quick structural pass, that trade usually wins.
The modes
- canny - edge map → generate an image that follows those contours. The classic for architecture, mechanical objects, anything with clear lines.
- depth - runs a local Depth Anything Small model (
depth-anything-small-hf) on your image and generates along the depth layout. Best when what matters is spatial arrangement - foreground/background separation, "what goes where". - coloring - the node grayscales your input and regenerates it in color. Colorization, not palette transfer.
- deblurring - the input gets Gaussian-blurred as the condition, and the model sharpens it. A surprisingly useful cleanup pass.
The inputs
- ref_image (
IMAGE) - the source. Resized to 512×512 internally. - prompt (
STRING) - what the result should depict. "blue", per the example workflow, when colorizing. - condition_type (enum) - the dropdown above:
canny,depth,coloring,deblurring. This selects which LoRA gets loaded (experimental/<type>.safetensors) and how the reference is preprocessed. - seed (
INT) - the noise seed.
Output is one image (IMAGE) at 512×512, straight into a SaveImage or PreviewImage. No KSampler, no separate FLUX loader - it's a self-contained generation node.
Installing it
ComfyUI Manager search ComfyUI_RH_OminiControl, or:
cd ComfyUI/custom_nodes
git clone https://github.com/HM-RunningHub/ComfyUI_RH_OminiControl
# restart ComfyUI
Models, again, are the whole game: FLUX.1-schnell in diffusers format at ComfyUI/models/flux/FLUX.1-schnell, the four mode LoRAs under ComfyUI/models/flux/OminiControl/experimental/, and - only for depth - the Depth Anything Small model at ComfyUI/models/flux/OminiControl/depth-anything-small-hf. No requirements.txt ships; the README recommends diffusers 0.31.0, and opencv (cv2) is used for canny, so your ComfyUI env needs it.
Where people get burned
- Depth fails while the other three work. It's the only mode with a second model dependency. If you skipped
depth-anything-small-hf, depth errors while canny is fine. - No control strength. The
generate()call under the hood hardcodescondition_scaleat 1.0, so you can't dial the condition down when it overcooks. It's a one-shot, not a tuning instrument. - The seed quirk.
seed % (2 ^ 16)- and^is bitwise XOR, so that's modulo 18. Roughly 18 outcomes; don't chase seeds. - 512×512 fixed. Structure-heavy work wants resolution; plan an upscale pass if it matters.
- The whole pipeline is bf16, so Ampere-or-newer NVIDIA hardware (the author targets a 4090) is effectively required.
Where this fits in a real workflow: use the depth or canny pass to lock composition, then carry the result into a proper sampler graph or an edit model for the details. It's a fast structural sketch on FLUX with zero ControlNet plumbing - and for that narrow job it's hard to beat.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| ref_image | IMAGE | — | |
| prompt | STRING | — | |
| condition_type | COMBO | 4 options: canny, depth, coloring, deblurring | |
| seed | INT | 00–18446744073709550000 | The random seed used for creating the noise. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |