kubakub scene relight
Lamps, HDRI and a projection as a light source — lighting your building in Cycles
- scene
- emission_masks
- projector
- clay_color
- viewer
- image
- alpha
- report
- plan
Here's the thing no previz in this pack can tell you except this one: a projection only shows where the lamps leave the wall dark. Point a 30,000 lumen projector at a facade that's already lit by street lamps and shop windows and you get a pale ghost of your content. Point it at an unlit stone wall at 2 a.m. and it looks like magic. kubakub scene relight renders the model in Cycles so you can see which of those two you're getting.
It's the only node in the pack that actually solves light transport - real shadows, real bounces, real falloff. And it understands the two things that matter here: lamps placed in facade metres, and the projection itself as an emitter.
The lighting inputs
environment picks the ambient light: Blender's built-in HDRIs, your own file, or none for "only the lamps I placed". env_strength (default 0.3) is the obvious dial - 0 kills ambient entirely. env_rotation_deg turns the HDRI around the vertical axis, which is how you move the moon or a sky glow to wherever it flatters the building. With environment = file and an empty hdri_file, the node quietly falls back to the built-in night environment and says so in the report.
lights is a text field with one light per line, in metres from the frame centre / the ground / the wall:
area -9 6 6 900 #ffd2a0 4
area 9 6 6 900 #ffd2a0 4
point 0 1 1 150 #ff9a50 0.3
sun azimuth elevation strength [#colour]
point, area and spot take x, height and distance-from-the-wall plus watts, an optional colour and an optional size (or cone angle). sun takes azimuth and elevation instead of a position.
You don't have to type it. Below the inputs the node draws a top view of the place, audience at the bottom, and you drag lamps around on it - drag for x and distance, mouse wheel for height, click to edit watts, colour, size or angle; a sun gets dragged around the rim. The plan writes the lights text and follows it when you type, so the text stays the single source of truth. The live pill under the plan requeues the workflow every time you move something, which is how you walk a lamp around a square and get one image after another.
clay and roughness describe the material of everything: how bright the surface is, and how matte. roughness at 1 is matte stone, lower is shinier - and stone with a bit of sheen reads far better in a lamp-lit shot. samples (64, denoised) and exposure (stops) are your quality and brightness dials. resolution_scale renders small for a quick look and scales back up to the matrix size. background chooses what shows where there's no building.
The projection, and glow
projector takes your matrix image (first frame of a batch only - for moving pictures use the director or kubakub pieces render) and casts it from the projection camera with distance falloff, surface angle and occlusion. In projector_mode = light it shines by itself, like a real projector - that's the mode for a projection. In paint it becomes the wall's colour and is only as bright as the lamps make it, which is exactly the right mode for textures on a building rather than a mapped show.
emission_masks is the sleeper feature: connect masks at matrix size (director layer masks, a region mask) and the faces they cover become emissive - they glow, and they light the stone around them. emission_colors gives one colour per mask, emission_strength sets how hard they burn. A glowing window that spills onto the wall next to it is the difference between a lit room and a sticker.
view is tone mapping and it's where people get burned. Neutral (default) keeps your projected picture's colours even when it's bright - this is the one for projections. Standard shows exact colours until they clip to white. AgX is filmic and lovely for lamp moods, but it bleaches a projection towards white however hard you push it. If your projection looks milky and washed, check view before you touch projector_brightness.
Camera and outputs
camera decides the view: projector gives the matrix view of the building alone (content, or a base layer for the director); audience puts you in the street with its surroundings (via kubakub scene surroundings), with distance, offset, eye height and lens, and a draggable ring on the plan; previz reuses the exact spot, lens and size of kubakub scene preview - connect its scene output and pick the spot number.
Outputs: image (the relit view), alpha (1 where the building is), report (size, lights, environment, samples, glowing faces, render time), and plan - the light plan, which is genuinely good to put in a client deck: every lamp in its colour with its number and height, the model in orange, the projector as a dot, the camera as a ring.
Install
cd ComfyUI/custom_nodes && git clone https://github.com/kubakubkub/ComfyUI_KubaNodes
python -m pip install -r ComfyUI_KubaNodes/requirements.txt
Blender 4.x is required - this is Cycles, run headless. The pack keeps a Blender worker alive between jobs (blender_idle = 600), and caches relit frames on disk under ComfyUI/user/kubakub_cache (cache_gb = 20 by default, least recently used first). Fiddling with lamps doesn't re-render what didn't change - but it will re-render plenty, so drop resolution_scale to 0.3 and samples to 16 while you're placing lights.
One gotcha with no error message attached: this node doesn't show its render on itself any more. Connect a Preview Image to image.
And the other one, which is really about expectations: a projection can't brighten a surface that's already brighter than it. If a district has decided to leave its architectural lighting on during your show, no exposure value fixes that.
Inputs (29)
| Name | Type | Default | Description |
|---|---|---|---|
| scene | KUBA_SCENE | From kubakub scene render. | |
| environment | COMBO | night | Blender's built-in HDRIs, 'file' = hdri_file, 'none' = only your lights. |
| env_strength | FLOAT | 0.300–50 | Brightness of the HDRI environment light; 0 = only your lights. |
| env_rotation_deg | FLOAT | 0-360–360 | Turns the HDRI around the vertical axis (degrees), to move the sun or sky glow. |
| lights | STRING | // type x height distance watts #colour size / angle (metres from the frame centre, the ground, the wall) area -9 6 6 900 #ffd2a0 4 area 9 6 6 900 #ffd2a0 4 point 0 1 1 150 #ff9a50 0.3 | One light per line: 'point|area|spot x height distance watts [#colour] [size|angle]' in metres (x from the frame centre along the wall, height above the ground, distance from the wall), or 'sun azimuth elevation strength [#colour]'. |
| clay | FLOAT | 0.700–1 | Brightness of the clay material. |
| roughness | FLOAT | 0.800–1 | Roughness of the clay material: 1 = matte stone, lower = shinier. |
| samples | INT | 641–4096 | Cycles samples (denoised). |
| exposure | FLOAT | 0.0-10–10 | Overall exposure in stops: +1 = twice as bright, -1 = half. |
| background | COMBO | black | What shows where there is no building. |
| resolution_scale | FLOAT | 1.000.1–1 | Render smaller for quick looks; the output is scaled back to the matrix size. |
| emission_masksopt | MASK | Masks at matrix size (director layer masks, regions mask ...): faces covered by a mask glow. A batch = several emitters. | |
| emission_colorsopt | STRING | #ffb060 | One colour per mask, comma separated (the last one repeats). |
| emission_strengthopt | FLOAT | 200–10000 | Emission strength of the glowing faces. |
| hdri_fileopt | STRING | An .hdr / .exr for environment = file. Empty: the built-in night environment is used instead and the report says so. | |
| projectoropt | IMAGE | Only the first frame of a batch is used. Your projection picture (the matrix, as on scene preview): it is cast from the projection camera like a real projector, with falloff, surface angle and the shadows other lamps would not show. With camera = audience you see the building with your picture on it, in its street, under your lamps. | |
| projector_brightnessopt | FLOAT | 1.000–100 | 1 = the image lands at about its own brightness on a frontal wall. |
| projector_modeopt | COMBO | light | light = cast from the camera like a real projector: this is the one for a projection, it shines by itself. paint = the image becomes the model's colour (textures on the building) and is only as bright as the lamps and HDRI make it: dark at night. |
| viewopt | COMBO | Neutral | Tone mapping. Neutral = the projected picture keeps its colours, also when it is bright (the one for a projection). AgX = filmic, soft highlights for lamp moods, but it bleaches a projection towards white. Standard = no tone mapping: exact colours until they clip to white. |
| clay_coloropt | COLOR | #ffffff | Colour of the clay material (the building and its surroundings); 'clay' sets how bright it is. White = neutral grey clay, as before. |
| cameraopt | COMBO | projector | projector = the matrix view, the building alone (content, a base for the director). audience = from a spot in front of the building, with its surroundings (kubakub scene surroundings): the lit place as a visitor sees it; drag the ring on the plan to move it. previz = the very viewpoint of kubakub scene preview (connect its scene output): same spot, lens and size. |
| audience_distance_mopt | FLOAT | 30.00.5–2000 | camera = audience: metres in front of the wall (the 'distance' of a scene preview spot). |
| audience_offset_mopt | FLOAT | 0.0-1000–1000 | camera = audience: metres left (-) or right (+) along the wall (the 'x' of a scene preview spot). |
| eye_height_mopt | FLOAT | 1.70–500 | camera = audience: eye height above the ground; 20-60 for a view from above. |
| lens_mmopt | FLOAT | 246–300 | camera = audience: focal length (smaller = wider). |
| plan_width_mopt | FLOAT | 00–3000 | How many metres the light plan shows across. 0 = fitted to the lamps, the projector and the audience; larger to see more of the surroundings. |
| previz_spotopt | INT | 11–64 | camera = previz: which spot of scene preview (its line in 'spots'). |
| audience_turn_degopt | FLOAT | 0-180–180 | camera = audience: turns the camera away from the middle of the facade, in degrees (+ = to the right). On the plan: drag the small dot in front of the ring. |
| vieweropt | KUBA_VIEWER | The audience spot of kubakub scene measure / project settings, one spot for all nodes. With camera = audience it replaces audience_distance_m, audience_offset_m and eye_height_m of this node (dragging the ring on the plan then does not move the camera). |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | The relit clay from the projection camera, or from the audience. |
| alpha | MASK | 1 where the building is (camera = audience: and its surroundings). |
| report | STRING | Size, lights, environment, samples, glowing faces and render time. |
| plan | IMAGE | Top view of the light plan, the audience at the bottom: every lamp in its colour with its number (the line in 'lights') and height, the model (orange), the projector (dot), the audience camera (ring) and the surroundings (grey). |