Nodes/ComfyUI-AI-Assistant/Apply Lighting Effects
ComfyUI Node

Apply Lighting Effects

This Node Relights a Normal Map — Feed It a Photo and It Looks Like Garbage

By JackEllie·Created 2 years ago·Updated 2 years ago· 24
Apply Lighting Effects
  • image
  • image
  • show_help
light_yaw60.0
light_pitch-60.0
specular_power30.00
normal_diffuse_strength1.00
specular_highlights_strength0.80
total_gain0.60

First thing to know about Apply Lighting Effects: it's a normal-map relighter, not a photo filter. You feed it a normal map - the blue-purple RGB image that ControlNet's normal preprocessors produce - and it shades it like a 3D surface with a virtual light source. Feed it a regular photograph and you'll get something that looks like a bad shader test, because the node is treating your pixel colors as surface normals. That's not a bug; it's the whole premise.

Where does that leave you? If you're building lineart → normal → 3D or normal-based shading workflows, this is the missing shading step. The pack's README shows exactly those pipelines: lineart to normal, then normal to a lit result, plus the "anime shadow" and "coloring" examples. It comes from the same family of Japanese preprocessor packs that treat lineart and normal maps as first-class workflow inputs, so think of it as the "put a lamp on your normal map" node.

How it works

Under the hood it's a compact Phong-style lighting model. The input image's RGB channels get normalized into unit vectors - that's the "treat colors as normals" bit. Then it computes two terms against a light direction derived from light_yaw and light_pitch:

  • Diffuse: dot product of the normal with the light vector, clamped to 0–1.
  • Specular: dot product with the half-vector (light + camera), raised to specular_power. Higher power = tighter, shinier highlights.

Those get scaled by normal_diffuse_strength and specular_highlights_strength, then the whole thing is multiplied by total_gain to bring it into a printable range. The output is a grayscale shaded version of the normal map - bright where surfaces face the light, dark where they fall away.

The inputs that matter

The author ships a reference table in the node's own show_help output (in Chinese), mapping light directions to yaw/pitch values:

  • Light from the front: light_yaw: 60, light_pitch: -60
  • Upper-left: light_yaw: 40, light_pitch: -60
  • Upper-right: light_yaw: 60, light_pitch: -40
  • From the left: light_yaw: 0, light_pitch: 0 · From the right: light_yaw: 90, light_pitch: 0 · From below: light_yaw: 45, light_pitch: 0

Honestly, that table feels arbitrary - the mapping isn't intuitive, so the practical move is to treat yaw and pitch as dials and watch the preview. Start from one preset, then nudge. specular_power (default 30), specular_highlights_strength (0.8) and total_gain (0.6) are the controls for how glossy and how bright the result is; you'll mostly touch total_gain to stop things blowing out. Outputs are image (the shaded result) and show_help (that reference text, which you can dump into a text viewer).

Installing it

It's part of JackEllie/ComfyUI_AI_Assistant, a small fork of tori29umai0123's AI-Assistant. Install via ComfyUI Manager (search "ComfyUI-AI-Assistant") or:

cd ComfyUI/custom_nodes
git clone https://github.com/JackEllie/ComfyUI_AI_Assistant

Restart after. No model downloads - this is a pure math node running on the image tensor. The pack declares only opencv-python as a dependency, but imports skimage at module load; if the whole pack won't load, pip install scikit-image usually fixes it.

Gotchas

The "feed it a photo and it looks broken" thing above is the #1 user error - normal maps only. Also keep in mind the output is effectively single-channel shading, so wire it where a grayscale-ish image is acceptable, and check your downstream node accepts it. And if the lighting direction presets seem backwards to you, you're not crazy: yaw 0 with pitch 0 is "from the left" in this author's scheme, so trust the preview, not your intuition.

Categoryadvanced/AI_Assistant/image

Inputs (7)

NameTypeDefaultDescription
imageIMAGE
light_yawFLOAT60.0-180–180
light_pitchFLOAT-60.0-90–90
specular_powerFLOAT30.0010–100
normal_diffuse_strengthFLOAT1.000–5
specular_highlights_strengthFLOAT0.800–5
total_gainFLOAT0.600–1

Outputs (2)

NameTypeDescription
imageIMAGE
show_helpSTRING