PostFx Apply
Put a film stock on your generations without burning a diffusion pass
- image
- look
- mask
- image
PostFx Apply is the whole point of the ComfyUI-PostFx pack, and the argument it makes is one you should hear early: your generated image is fine, it just doesn't look like it was shot yet. This node slaps a film stock or cinematic grade onto any image batch - Portra 400 skin tones, Cinestill 800T halation, a teal-orange blockbuster pass - deterministically, on the CPU, in a fraction of a second. No model, no API key, no extra VRAM. That's the "cheap deterministic primitive before the expensive generative one" play from the KB's post-processing layer: the same job people routinely waste a whole re-roll (or worse, an img2img pass that rewrites the subject's face) on, done in one node.
The engine underneath is the author's postfx pipeline, a numpy-based processor that ComfyUI-PostFx wraps. Everything runs on CPU because everything is classic pixel math: color transforms, grain, vignette, halation, sharpen. A theme is a full look (color grade plus grain and lens character) defined in YAML - there are 31 built in, named after real stocks and industry grades. A condition is a separate axis that scales only the texture stuff - grain, chroma noise, halation - to match a shooting situation, without touching color. That split is the clever bit: one theme stays consistent across conditions because the grade doesn't move, only the "how was this lit/scanned" texture does.
Here's what you actually set:
- theme - the 31-entry dropdown, default
01_portra_400. Picking this alone gets you 80% of the value. - condition -
neutral(default),day_outdoor,overcast,indoor_evening,neon_night,night_flash. Start at neutral, then tryneon_nighton a city shot - it's a vibe. - strength - 0.0 to 1.5, default 1.0. Linearly blends the whole effect with the original; 0 is untouched, >1 is deliberately overdone. This is your "keep it subtle" knob.
- seed and batch_seed - grain is deterministic (same seed, same grain).
batch_seed = incrementgives each frame its own grain, which you want for animation or video so the noise doesn't crawl in a fixed pattern.
The optional inputs are where it gets interesting. A look connected from a PostFx Theme / Custom Look / LUT node overrides the theme dropdown entirely - that's how the pack's chain workflow works. A mask limits the effect to where the mask is white and blends back to the original elsewhere (the code does a straight original * (1-mask) + effect * mask), which is handy if you want the grade on a subject but not the background. Output is a single image of type IMAGE, straight into Save Image or onward to upscaling.
Installing is ComfyUI Manager (search ComfyUI-PostFx) or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/0xBeycan/ComfyUI-PostFx.git
pip install -r ComfyUI-PostFx/requirements.txt
Restart ComfyUI and the nodes appear under PostFx. The only real dependency is postfx>=1.0 (plus numpy and opencv under the hood) - tiny, CPU-only, no model downloads. There is no giant checkpoint to fetch.
Where people get burned: forgetting that a connected look silently ignores your theme dropdown (it's by design - the tooltip says so, but it reads as a bug the first time). And if grain looks wrong at your resolution, don't panic - grain scales with image size by design, so a look reads the same at 512 or 2048. Deterministic and resolution-safe is the whole selling point, and the pack delivers it.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| theme | COMBO | 01_portra_400 | Built-in look. Ignored when a 'look' input is connected. |
| condition | COMBO | neutral | Shooting condition: scales grain/chroma/halation only. |
| strength | FLOAT | 1.000–1.5 | 0 = original, 1 = full look, >1 = over. |
| seed | INT | 00–4294967295 | Grain seed (deterministic). |
| batch_seed | COMBO | fixed | increment = a different grain per frame across the batch. |
| lookopt | POSTFX_LOOK | A look from a PostFx Theme / Custom Look / LUT node. Overrides 'theme'. | |
| maskopt | MASK | Apply the effect only where the mask is white; blend with original. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |