Nodes/ComfyUI-TextureAlchemy/Normal Map Relighter (IBL + PBR)
ComfyUI Node

Normal Map Relighter (IBL + PBR)

Albedo, Roughness, Metallic and an HDRI

By amtarr·Created 9 months ago·Updated 4 months ago· 58
Normal Map Relighter (IBL + PBR)
  • diffuse_image
  • normal_map
  • environment_map
  • roughness_map
  • metallic_map
  • irradiance_map
  • relit_image
  • diffuse_lighting
  • specular_lighting
  • diffuse_color
  • key_light_direction
environment_rotation0
diffuse_intensity1.0
specular_intensity1.0
ambient_light0.10
roughness_multiplier1.0
roughness_affects_diffuse0.50
diffuse_contrast1.0
use_colored_diffusefalse
diffuse_qualityFlat Ambient (No Direction)
normal_formatOpenGL

Everything the IBL relighter does, but now it reads your actual PBR material. Feed it the albedo, the normal map, and an environment map, and it shades the whole thing the way a game engine would - diffuse light wrapped by the environment, specular reflections that get sharper on smooth surfaces and blurrier on rough ones, and optional metallic and roughness maps that decide how much of each you see. This is the "render preview in your node graph" node.

Where the basic IBL version treats every pixel the same, this one lets the material speak. A scratch on a painted surface picks up a highlight; a matte rubber part doesn't. If you've ever built a PBR set and only seen it look right once you imported it into Blender or Unity, this node saves you that round-trip.

How it works

Same core as its sibling: normal map → vectors → sample the equirect environment for diffuse, compute reflection vectors R = 2(N·V)N − V and sample for specular. The PBR additions are what make it interesting:

  • roughness_map (optional) blurs the specular locally - smooth areas get sharp reflections, rough areas smear them. roughness_multiplier scales the whole map, and roughness_affects_diffuse (0-1) decides how much roughness also blurs the diffuse pass.
  • metallic_map (optional) shifts the balance between diffuse and specular per pixel - metal reflects instead of diffusing, which is the classic PBR split.
  • irradiance_map (optional) replaces the raw environment sampling for diffuse with a pre-blurred irradiance-style sample; if you have one, the diffuse stops looking like a mirror of the sky.

The knobs that matter

  • diffuse_quality - six presets from "Flat Ambient (No Direction)" (pure even light) up to "True Hemisphere Sampling." Start at the default and move up only if the flat look isn't what you need; each step costs a bit more compute.
  • use_colored_diffuse - off by default means grayscale shading only; flip it on to let environment colors bleed into the diffuse.
  • diffuse_contrast - softness/contrast of the diffuse highlights. The tooltip's tip about lowering it to reduce the "metallic look" is worth remembering.
  • environment_rotation - spin the HDRI from −180 to 180 to find the hero angle.

Outputs

Five of them: relit_image (final), diffuse_lighting and specular_lighting (separate passes for comping), diffuse_color (the environment's colored contribution), and key_light_direction - a visualization of where the strongest light sits, which is handy when you're trying to match lighting between shots.

Installing it

In TextureAlchemy: ComfyUI Manager (search "TextureAlchemy"), or

cd ComfyUI/custom_nodes
git clone https://github.com/amtarr/ComfyUI-TextureAlchemy

Restart, then Texture Alchemist → Lighting. Purely image-in/image-out; no models, no dependencies beyond ComfyUI's own torch.

Where it sits in the family

The base relighter is a directional light; Advanced adds specular and color; IBL adds an environment. This node is the most complete of the four - it's the one you'd actually use to preview a finished PBR material set. Just remember it's still a screen-space approximation: no real ray tracing, no global illumination. For material preview it's superb, for final lighting you still ship to a renderer.

CategoryTexture Alchemist/Lighting

Inputs (16)

NameTypeDefaultDescription
diffuse_imageIMAGEAlbedo/diffuse color map
normal_mapIMAGE
environment_mapIMAGE
environment_rotationFLOAT0-180–180Rotate environment map (degrees)
diffuse_intensityFLOAT1.00–10Diffuse lighting intensity
specular_intensityFLOAT1.00–10Specular reflection intensity
ambient_lightFLOAT0.100–1Ambient light level
roughness_multiplierFLOAT1.00–2Global roughness multiplier (affects both diffuse and specular blur)
roughness_affects_diffuseFLOAT0.500–1How much roughness affects diffuse detail (0=uniform, 1=fully controlled by roughness)
diffuse_contrastFLOAT1.00–2Diffuse softness control (0=soft/compressed highlights, 1=normal, 2=enhanced contrast). Lower values reduce metallic look
use_colored_diffuseBOOLEANfalseUse environment colors for diffuse (False = grayscale shading only)
diffuse_qualityCOMBOFlat Ambient (No Direction)Diffuse quality - Flat Ambient = pure even lighting (no reflection look)
normal_formatCOMBOOpenGLNormal map format
roughness_mapoptIMAGE
metallic_mapoptIMAGE
irradiance_mapoptIMAGE

Outputs (5)

NameTypeDescription
relit_imageIMAGE
diffuse_lightingIMAGE
specular_lightingIMAGE
diffuse_colorIMAGE
key_light_directionIMAGE