ControlNet Script
Three ControlNet units, one node, each with its own switch
- positive
- negative
- image_1
- mask_1
- image_2
- mask_2
- image_3
- mask_3
- preprocessed_image_1
- preprocessed_image_2
- preprocessed_image_3
- positive
- negative
Take ControlnetUnit from this same pack, staple three of them together, and give each one its own enable/disable toggle - that's ControlNetScript. Instead of wiring three separate ControlNet nodes and bypass-muting whichever ones you don't need this generation, you wire your three image/mask sources into fixed slots once, and flip each slot on or off per run.
Why you'd want three at once
Stacking ControlNets is a completely normal move - canny plus depth for edge structure and spatial layout together, OpenPose plus depth for a posed figure that respects scene depth, lineart plus a reference pass for structure plus style. Each unit runs with its own independent weight and step-range settings and blends into the same conditioning. This node just gives you a fixed three-slot template for that pattern instead of assembling it from scratch every time.
The shape
Everything here comes in threes: is_enabled_1/2/3 (each defaulting to disable), preprocessor_name_1/2/3, control_net_name_1/2/3, strength_1/2/3, threshold_a_1/2/3 and threshold_b_1/2/3, start_percent_1/2/3 and end_percent_1/2/3, resolution_1/2/3, and optional image_1/2/3 plus mask_1/2/3 - each set identical in shape to ControlnetUnit's own fields, just numbered. One shared positive/negative conditioning pair flows through whichever slots are actually enabled.
All three slots default to disable. Nothing runs out of the box - you wire in what you have, then flip is_enabled_N to enable only for the slots you're actually using this generation. That's the whole point of the design: leave a canny source permanently wired to slot 1, a depth source to slot 2, and toggle each one on or off per shot without touching the wiring.
Outputs: preprocessed_image_1/2/3 - one hint-map preview per slot - plus the final positive/negative conditioning after every enabled slot has been applied, ready for KSampler.
ControlnetUnit or ControlNetScript?
Reach for the standalone ControlnetUnit if you only need one condition, or if you need more than three (chain several in series). Reach for ControlNetScript when you know ahead of time you're working with a fixed two- or three-condition template - canny always available, depth and pose toggled per shot - and you'd rather flip a switch than mute a node.
Same era caveat as ControlnetUnit. This pack predates ControlNet's modern union checkpoints, so control_net_name_N still expects one model per condition - a canny-trained checkpoint for a canny preprocessor, a depth-trained one for a depth preprocessor. Pairing the wrong preprocessor with the wrong checkpoint doesn't error, it just quietly does nothing useful.
Installing it
ComfyUI Manager: search "Comfy-Photoshop-SD" and install, then separately install "ComfyUI's ControlNet Auxiliary Preprocessors" (Fannovel16/comfyui_controlnet_aux) - the README calls this out explicitly as a requirement for using ControlNet at all in this pack. By hand:
cd ComfyUI/custom_nodes
git clone https://github.com/AbdullahAlfaraj/Comfy-Photoshop-SD
git clone https://github.com/Fannovel16/comfyui_controlnet_aux
Restart ComfyUI, and make sure at least one ControlNet checkpoint is sitting in models/controlnet before you expect any control_net_name_N dropdown to have options.
Where people get burned
The most common confusion is wiring an image and mask into a slot, expecting it to run, and forgetting that is_enabled_N - not the wiring - is what actually decides whether that slot does anything. Check the toggle first if a slot seems to be ignored. Beyond that, this pack's ControlNet integration has a track record of being version-sensitive: there's a real community report of Auto-Photoshop-SD's ControlNet breaking after an update, traced back to the Photoshop plugin, its extensions, and this ComfyUI pack drifting out of sync with each other. If ControlNet stops working after you update any one piece of this chain, check that the others are current too before you start debugging your graph.
Inputs (35)
| Name | Type | Default | Description |
|---|---|---|---|
| positive | CONDITIONING | — | |
| negative | CONDITIONING | — | |
| is_enabled_1 | COMBO | disable | 2 options: disable, enable |
| preprocessor_name_1 | COMBO | 26 options: None, CannyEdgePreprocessor, OpenposePreprocessor, HEDPreprocessor, FakeScribblePreprocessor, InpaintPreprocessor, +20 | |
| control_net_name_1 | COMBO | 1 options: None | |
| strength_1 | FLOAT | 1.000–10 | — |
| threshold_a_1 | FLOAT | 0.00 | — |
| threshold_b_1 | FLOAT | 0.00 | — |
| start_percent_1 | FLOAT | 0.0000–1 | — |
| end_percent_1 | FLOAT | 1.0000–1 | — |
| resolution_1 | INT | 51264–2048 | — |
| is_enabled_2 | COMBO | disable | 2 options: disable, enable |
| preprocessor_name_2 | COMBO | 26 options: None, CannyEdgePreprocessor, OpenposePreprocessor, HEDPreprocessor, FakeScribblePreprocessor, InpaintPreprocessor, +20 | |
| control_net_name_2 | COMBO | 1 options: None | |
| strength_2 | FLOAT | 1.000–10 | — |
| threshold_a_2 | FLOAT | 0.00 | — |
| threshold_b_2 | FLOAT | 0.00 | — |
| start_percent_2 | FLOAT | 0.0000–1 | — |
| end_percent_2 | FLOAT | 1.0000–1 | — |
| resolution_2 | INT | 51264–2048 | — |
| is_enabled_3 | COMBO | disable | 2 options: disable, enable |
| preprocessor_name_3 | COMBO | 26 options: None, CannyEdgePreprocessor, OpenposePreprocessor, HEDPreprocessor, FakeScribblePreprocessor, InpaintPreprocessor, +20 | |
| control_net_name_3 | COMBO | 1 options: None | |
| strength_3 | FLOAT | 1.000–10 | — |
| threshold_a_3 | FLOAT | 0.00 | — |
| threshold_b_3 | FLOAT | 0.00 | — |
| start_percent_3 | FLOAT | 0.0000–1 | — |
| end_percent_3 | FLOAT | 1.0000–1 | — |
| resolution_3 | INT | 51264–2048 | — |
| image_1opt | IMAGE | — | |
| mask_1opt | IMAGE | — | |
| image_2opt | IMAGE | — | |
| mask_2opt | IMAGE | — | |
| image_3opt | IMAGE | — | |
| mask_3opt | IMAGE | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| preprocessed_image_1 | IMAGE | — |
| preprocessed_image_2 | IMAGE | — |
| preprocessed_image_3 | IMAGE | — |
| positive | CONDITIONING | — |
| negative | CONDITIONING | — |