LC Lighting Control V2 ๐ฆ
Relight a finished image with real cast shadows, no re-generation
- image
- normal_map
- depth_map
- mask
- image
- shadow_mask
- light_layer
Most "relighting" in ComfyUI means pushing your picture back through a diffusion model - IC-Light and friends - and hoping the identity, the logo on the shirt and the stitching survive. LC Lighting Control V2 is narrower and much safer: give it your image plus a normal map and a depth map and it repaints the light mathematically. No sampler, no second pass, no re-generation. The pixels you spent an hour on stay the pixels you spent an hour on.
The tradeoff is honest: it can't invent light it can't compute, and it has no idea a surface is brushed aluminium. But for "this render is lit from the wrong side", "this product shot needs a window light", or "I need a rim light behind the subject" - it's instant, deterministic, and the face can't drift.
V1 (LC Lighting Control ๐ฆ) still ships and still works - V2 is a separate node, not a replacement.
How it works
The normal map is decoded from RGB to unit vectors, and depth is normalised to 0 = near, 1 = far with a percentile stretch (auto-flipped if the map runs the other way). Each light adds a diffuse term from the normals: surface facing the light goes bright, surface turned away doesn't.
Cast shadows are where V2 earns its name. Depth becomes a height field and rays are marched along the light direction with elevation included, so shadow length follows the light's height and shadows soften with distance from the occluder. Depth edges get snapped toward the image's real edges first, and if you feed the optional subject mask, the subject lifts off the background to throw a clean shadow onto it.
V1 was shading. V2 is shading plus geometry.
Inputs and outputs
Required: image, normal_map, depth_map. Optional: mask (subject matte - LC's own background-removal or person-mask nodes, or SAM).
Start with preset (Rembrandt, Soft window left/right, Split (hard side), Top light, Under light, Rim, Golden hour, Campfire, Cyberpunk, Key + fill, Flat front). It sets the lights and shadows; touch anything and it flips to custom. The three you'll actually turn:
blend- the safety valve. 0 is the original, 1 is fully relit, and 0.7โ0.9 is where this looks like a photograph rather than a filter.light1_x/light1_y/light1_z- where the light is. X left/right, Y up/down, Z how frontal. Or just drag the handle on the node's light stage (Shift+drag or wheel for Z).shadowsplusshadow_amount/shadow_blur- soft, hard or off. Hard is a sun or a bare bulb; soft is a window.
An advanced toggle reveals the fine controls (relief, depth_falloff, shadow_height, shadow_length, shadow_softness, subject_distance, mask_dome). The one to know is relief - how deep the face is in 3D, and what decides whether a nose casts a nose-shaped shadow or nothing. shadow_height sets shadow length independently of the light's Z.
Outputs: image (relit), shadow_mask (white = lit, black = in shadow - genuinely useful as a matte), and light_layer (the normalised illumination buffer, handy for compositing).
Install
Manager โ ComfyUI LC123 Nodes, or:
cd ComfyUI/custom_nodes
git clone https://github.com/lonecatone23/ComfyUI_LC123_nodes.git
Restart. No pip install - it's NumPy and PyTorch, no SciPy or OpenCV.
The maps are on you. Depth Anything V2 (Kijai's or comfyui_controlnet_aux) is still the default depth preprocessor in 2026, V3 notwithstanding, and BAE/DSINE normal maps come from ControlNet Auxiliary Preprocessors. The README points at both, plus remBG for a subject mask. The example workflow is workflows/Lonecats Lighting Control Module V2.json.
Common issues
The lighting looks inside-out - the light is dark and the shadow side is bright. Your depth map is inverted. Bright-equals-near instead of near-equals-dark is the usual culprit; flip it. The node tries to auto-detect this, but it can be fooled by a subject filling the frame.
Grey fringe or halo around the subject when a mask is connected. The README's own advice: turn the mask off first to confirm, then lower the blend or tighten the matte. High blend with a soft mask fringes.
Faces go plasticky and flat. relief is too low for the face - you get shading with no self-shadowing. Raise it. Conversely, if you're getting long cobweb shadows off every strand of hair, it's too high.
Shadows crawl into the background or vanish. background_shadow is the control: 1 assumes a wall right behind the subject, 0 assumes a distant background. With no mask connected the node guesses this from the far part of the depth map, and it can guess wrong on a busy scene.
Nothing looks real. Check fill: at its default 0.18 shadows stay off black, at 0 everything unlit goes pitch dark, and past 0.5 the frame flattens out. And if you want a material-aware relight - real specular behaviour, at the cost of identity drift - this isn't the tool. That's an IC-Light pass.
Inputs (40)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image to relight. | |
| normal_map | IMAGE | Normal map of the same image (LC Normal Map). | |
| depth_map | IMAGE | Depth map of the same image (LC Depth Anything V2). | |
| preset | COMBO | Rembrandt | A starting look. Picking one sets the lights and shadows below, then you can adjust anything. Editing a light or shadow value switches this to custom. |
| blend | FLOAT | 0.800โ1 | How much of the relit result is mixed over the original. 0 = original, 1 = fully relit. 0.7 to 0.9 looks best. |
| light1_type | COMBO | spot | spot = a soft beam that lights part of the frame. sun = even light over the whole frame. |
| light1_x | FLOAT | 0.65-1โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. |
| light1_y | FLOAT | 0.60-1โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. |
| light1_z | FLOAT | 0.500โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. Z changes the shading and the beam. It does not change the shadow length. |
| light1_brightness | FLOAT | 1.400โ4 | How bright the light is. About 1.2 to 1.5 is a natural key light. |
| light1_spread | FLOAT | 0.900.05โ1.5 | Spot only: how wide the beam is. Small = tight spotlight, large = soft flood over the whole face. |
| light1_warmth | FLOAT | 0.10-1โ1 | Color of the light. Negative = cool blue, 0 = neutral, positive = warm orange. |
| light1_color | COMBO | none | Optional colored gel on this light. Works together with warmth. The color only shows where this light reaches, so shadows fall back to the neutral fill. |
| light1_color_amount | FLOAT | 0.500โ1 | How strong the colored gel is. 0.3 to 0.6 looks natural, 1 is a saturated stage light. |
| enable_light_2 | BOOLEAN | false | Add a second light (fill or rim). |
| light2_type | COMBO | spot | spot = a soft beam that lights part of the frame. sun = even light over the whole frame. |
| light2_x | FLOAT | -0.80-1โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. |
| light2_y | FLOAT | -0.10-1โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. |
| light2_z | FLOAT | 0.500โ1 | Where the light is on the stage: X = left/right, Y = down/up, Z = how frontal (0 side-on, 1 head-on). Drag the handle on the stage, or type here. Z changes the shading and the beam. It does not change the shadow length. |
| light2_brightness | FLOAT | 0.600โ4 | How bright the light is. About 1.2 to 1.5 is a natural key light. |
| light2_spread | FLOAT | 1.200.05โ1.5 | Spot only: how wide the beam is. Small = tight spotlight, large = soft flood over the whole face. |
| light2_warmth | FLOAT | -0.15-1โ1 | Color of the light. Negative = cool blue, 0 = neutral, positive = warm orange. |
| light2_color | COMBO | none | Optional colored gel on this light. Works together with warmth. The color only shows where this light reaches, so shadows fall back to the neutral fill. |
| light2_color_amount | FLOAT | 0.500โ1 | How strong the colored gel is. 0.3 to 0.6 looks natural, 1 is a saturated stage light. |
| light_wrap | FLOAT | 0.300โ1 | Softens where light turns to shade on the face and body. 0 = a sharp line like a hard lamp, higher = a gradual roll-off. |
| fill | FLOAT | 0.180โ1.5 | Base light that everything keeps, including the shadow side. 0 = pitch black shadows, 0.2 = natural, 0.5 = flat. |
| shadows | COMBO | soft | soft = edges soften away from the object. hard = sharp edges (sun, spotlight). off = no cast shadows, only shading. |
| shadow_amount | FLOAT | 0.550โ1 | How dark cast shadows get. They never go below the fill light. |
| shadow_blur | FLOAT | 0.350โ1 | Blurs the edges of cast shadows, in both soft and hard mode. Raise it if a shadow looks cut out. |
| background_shadow | FLOAT | 0.500โ1 | How much of the shadow shows on the background behind the subject. 1 = a wall right behind, 0 = a distant background with nothing near enough to catch a shadow. Uses the mask if connected, otherwise the depth map. |
| self_shadow | FLOAT | 0.500โ1 | Needs a mask. How strongly the subject shadows itself (nose, chin, hair) compared with the shadow it throws on the background. |
| relief | FLOAT | 0.300โ1 | How deep the face and scene are in 3D. More = longer, stronger shadows from noses, chins and hair. |
| advanced | BOOLEAN | false | Show the fine controls (depth, shadow shape, mask options). |
| depth_falloff | FLOAT | 0.400โ2 | Far areas get less light. 0 = no falloff. |
| shadow_height | FLOAT | 0.400โ1 | Height of the light for SHADOWS only. Low = long stretched shadows, high = short shadows right under things. Separate from Light Z. |
| shadow_length | FLOAT | 0.300.02โ1 | The farthest a shadow can reach (fraction of the image). |
| shadow_softness | FLOAT | 0.500โ1 | Soft shadows only: how quickly the edge softens with distance from the object. |
| subject_distance | FLOAT | 0.150โ1 | Needs a mask. How far the subject stands in front of the background, so it throws a shadow on it. 0 = flat against the wall. |
| mask_dome | FLOAT | 0.400โ1 | Needs a mask. Blends a rounded shape over the subject to smooth the form shading. |
| maskopt | MASK | Subject mask (LC Remove Background / LC Person Mask). Optional. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | โ |
| shadow_mask | MASK | โ |
| light_layer | IMAGE | โ |