Nodes/comfyui-reactor-node/Cinematic Enhancer 🌌 ReActor
ComfyUI Node

Cinematic Enhancer 🌌 ReActor

ReActor's Cinematic Enhancer is the de-AI pass hiding inside a face-swap pack

By GourieffΒ·Created 2 years agoΒ·Updated 4 days agoΒ· 1,385
Cinematic Enhancer 🌌 ReActor
  • image
  • depth_map
  • image
β—„intensity0.50β–Ί
β—„lut_fileβ–Ύβ–Ί
β—„lut_strength0.5β–Ί
β—„lut_gamma_correctiontrueβ–Ί
β—„film_grain_methodadvancedβ–Ί
β—„film_grain_power0.10β–Ί
β—„film_grain_scale1.0β–Ί
β—„film_grain_sat0.15β–Ί
β—„film_grain_shadows0.20β–Ί
β—„film_grain_highs0.20β–Ί
β—„film_blur_strength1β–Ί
β—„film_focal_depth0.90β–Ί
β—„film_focus_spread2.2β–Ί
β—„film_vignette_intensity0.10β–Ί
β—„cc_temperature0β–Ί
β—„cc_hue0β–Ί
β—„cc_brightness0β–Ί
β—„cc_contrast0β–Ί
β—„cc_saturation0β–Ί
β—„cc_gamma1.0β–Ί
β—„hdr_intensity0.50β–Ί
β—„hdr_shadow_intensity0.25β–Ί
β—„hdr_highlight_intensity0.75β–Ί
β—„hdr_contrast0.10β–Ί
β—„hdr_enhance_color0.25β–Ί

You installed ReActor for face swapping and got a colorist. The pack's 0.7.2 update added ReActorCinematicEnhancer - "Cinematic Enhancer 🌌 ReActor" in the node menu - and it's the least ReActor-ish node in the whole repo. No ONNX models, no face detection, no InsightFace weights, no license landmine. It takes a finished image, runs a stack of deterministic pixel operations over it, and gives you back something that reads a bit less like a render.

That's exactly the job this layer exists for. Post-processing is the pipeline stage people skip, and the mistake it prevents is trying to fix flat color or the "AI look" with another diffusion pass. A grain pass is additive noise. A LUT is a lookup table. Millisecond ops, no seed lottery, no re-rolled face. Gourieff's README pitch is blunt: "Forget about plastic skin and boring pictures… make any photorealistic image more soulful."

What it does to your pixels, in order

The node runs one fixed chain, and knowing the order explains most of the weird results:

LUT β†’ vignette β†’ depth blur β†’ color correction β†’ film grain β†’ HDR β†’ global blend.

If lut_file isn't none, it parses the file, optionally decodes gamma (lut_gamma_correction, default on: x^(1/2.2) before the LUT, x^2.2 after - what you want for LUTs authored in log or video gamma), then mixes the result back at lut_strength. Vignette is a radial multiply. Depth blur only fires if you connect depth_map. Color correction splits into PIL brightness/contrast and OpenCV-side temperature (positive warms red, negative cools blue), gamma, HSV hue rotation and saturation. Grain comes after color, which is right. Then HDR tone-maps in LAB luminance via ImageCms, and only then does intensity blend.

That last one is the whole design in one slider: intensity is a master wet/dry mix against the original image, applied at the very end. At 0 you get your input back pixel for pixel and every other knob is wasted. It defaults to 0.5, so half your grading gets thrown away before you see it. If you want to actually evaluate a look, push it to 1 while tuning.

The knobs a beginner actually sets

  • intensity - the mix. Start at 1.0, dial back to taste.
  • lut_file + lut_strength - drop .cube files in ComfyUI/models/luts (Gourieff keeps a pile on Hugging Face) and refresh. 0.3–0.5 strength is plenty.
  • film_grain_power - the de-AI knob, 0.05–0.15 for a whisper, and the main reason to open the node at all.
  • film_grain_method - advanced builds color noise, mixes it toward mono by film_grain_sat, scales it by film_grain_scale, and masks it by luminance so film_grain_shadows and film_grain_highs control how much lands in the dark and bright ends. fast is plain Gaussian noise at half amplitude and ignores those four fields. Advanced for stills, fast for video batches.

Output is a single IMAGE - wire it into SaveImage, a VAE Encode, or your video combine node. That's it. No hidden second output.

The depth_map slot

Optional, and it does one thing: fake depth of field. film_blur_strength sets the maximum blur radius (capped at 256px), film_focal_depth picks the in-focus plane (0.9 default, so near-ish), film_focus_spread controls falloff. The mask gets resized to your image if it doesn't match, and RGB depth is flattened to its first channel. No depth_map, no blur - and film_blur_strength defaults to 1 anyway, so nobody gets surprise blur.

Installing it

ComfyUI Manager β†’ Install Custom Nodes β†’ search "ReActor" β†’ install β†’ restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/Gourieff/ComfyUI-ReActor
cd ComfyUI-ReActor
install.bat        # Windows - install.py for Linux/macOS

colour-science is in the pack's requirements.txt, so the install script gets it for you. If you skipped the script, install it into the Python ComfyUI actually runs:

ComfyUI\python_embeded\python.exe -m pip install colour-science

You don't need inswapper, buffalo_l, or any face model for this node. You do need something in ComfyUI/models/luts, or the dropdown is just none.

Where people get burned

The node silently does nothing. No colour-science, no cinematic effect: the module catches the import failure, logs ReActorCinematicEnhancer is not available, please install 'colour' library to the console, and returns your image untouched. The graph runs green and you blame your settings. Check the console, not the image.

Non-.cube LUTs in the dropdown. The file picker lists .cube, .spi1d, .spi3d, .spimtx and .csp, but the code only ever calls read_LUT_IridasCube. Stick to .cube or you'll get an error mid-run.

film_grain_scale's tooltip is wrong. It claims 0.1..1; the range is 0.1–10 and the code divides resolution by the value, so above 1 the noise gets coarse - the direction you want for 35mm texture. Default 1 means "don't scale". Trust the slider, not the hint.

Grain in video sparkles. Every frame gets fresh noise with no temporal coherence, so subtle grain crawls across 24fps. Drop film_grain_power to near nothing for sequences, or call the sparkle "shot on film" and move on.

A saved workflow throws on a node that used to work. This node is beta and ReActor's input signatures have moved before. Delete the node, re-add it - the README's own first advice, and still the fastest fix.

Category🌌 ReActor/PostProcessing

Inputs (27)

NameTypeDefaultDescription
imageIMAGEβ€”
intensityFLOAT0.500–10..1, def: 0.5
lut_fileCOMBO1 options: none
lut_strengthFLOAT0.50–10..1, def: 0.5
lut_gamma_correctionBOOLEANtrueβ€”
film_grain_methodCOMBOadvanced2 options: advanced, fast
film_grain_powerFLOAT0.100–10..1, def: 0.1
film_grain_scaleFLOAT1.00.1–100.1..1, def: 0.1
film_grain_satFLOAT0.150–1(advanced only) 0..1, def: 0.15
film_grain_shadowsFLOAT0.200–1(advanced only) 0..1, def: 0.2
film_grain_highsFLOAT0.200–1(advanced only) 0..1, def: 0.2
film_blur_strengthINT10–256(by depth_map) 0..256, def: 1
film_focal_depthFLOAT0.900–1(by depth_map) 0..1, def: 0.9
film_focus_spreadFLOAT2.20.1–8(by depth_map) 0..8, def: 2.2
film_vignette_intensityFLOAT0.100–10..1, def: 0.1
cc_temperatureFLOAT0-100–100-100..100, def: 0
cc_hueFLOAT0-90–90-90..90, def: 0
cc_brightnessFLOAT0-100–100-100..100, def: 0
cc_contrastFLOAT0-100–100-100..100, def: 0
cc_saturationFLOAT0-100–100-100..100, def: 0
cc_gammaFLOAT1.00.2–2.20.2..2.2, def: 1.0
hdr_intensityFLOAT0.500–50..5, def: 0.5
hdr_shadow_intensityFLOAT0.250–10..1, def: 0.25
hdr_highlight_intensityFLOAT0.750–10..1, def: 0.75
hdr_contrastFLOAT0.100–10..1, def: 0.1
hdr_enhance_colorFLOAT0.250–10..1, def: 0.25
depth_mapoptIMAGEβ€”

Outputs (1)

NameTypeDescription
imageIMAGEβ€”