Post Polish (Film Touch)
A last-pass micro-texture shot, not a color grade
- image
- image
The most common tell of a generated image isn't composition or anatomy - it's that everything is too clean. Skin comes out poreless, surfaces come out sterile, and the image sits in an uncanny valley where it's sharp but somehow fake. Post Polish (Film Touch) is the pack's answer to the last of those: after VAE Decode, it applies a subtle tone S-curve and a whisper of film grain to put micro-texture back into the frame. It's the last node in the chain, a finishing touch rather than a fix.
It lives in the SDXL Adherence pack (regiellis/ComfyUI-SDXL-Adherence), and the honest framing is that it does a small thing well and doesn't pretend to be a colorist.
How it works
Two operations, both tiny by design. _s_curve is a soft contrast bump: each pixel is pushed away from mid-gray by (1 + tone_strength), clamped to [0,1]. That's it - no lifted shadows, no split toning, just a touch more separation so the image reads punchier without clipping. The second is grain: random noise, blurred with a small 3×3 kernel so it reads as film texture rather than speckle, added at grain_strength scale. The defaults are deliberately timid - tone at 0.1, grain at 0.02 - because the whole point is texture you barely notice until you compare side by side.
One detail worth knowing: the grain is torch.randn with no seed input, so it's not deterministic between runs. Same workflow, same everything, two runs - the grain pattern differs. For a photo look nobody will ever notice; if you're batch-generating and comparing frames pixel-for-pixel, it'll keep you honest.
Inputs and outputs
image- your decoded image, H×W×C or batched.film_touch- master toggle, default on. Flip it off and the node passes the image through untouched.tone_strength- 0–0.5, the contrast bump.grain_strength- 0–0.2, the grain amount.
Output is a single image - same shape as what you fed in, so it slots in anywhere a plain image would.
Installing it
Same single install as every node in this pack:
cd ComfyUI/custom_nodes
git clone https://github.com/regiellis/ComfyUI-SDXL-Adherence
Restart ComfyUI, or grab "SDXL Adherence" from ComfyUI Manager. No models, no extra dependencies.
Where people get burned
- Cranking the grain. Above ~0.05 it stops reading as film and starts reading as noise, especially on smooth skies and backgrounds. If you're tempted to push it, push
tone_strengthinstead and keep grain near default. - Placing it early. It's a finishing node. Run it before your upscaler or a second detail pass and you'll just be re-smoothing over the grain you added. Put it after the final decode.
The pack markets this as "film touch," and the marketing is accurate - it's closer to what a subtle grain LUT does than to a serious grade. If your output looks flat, this is a one-node way to find out whether micro-texture was the missing ingredient.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| film_touch | BOOLEAN | true | — |
| tone_strength | FLOAT | 0.100–0.5 | — |
| grain_strength | FLOAT | 0.0200–0.2 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |