Texture Delight
Texture Delight flattens it properly
- image
- mask
- image
- mask
- delight_info
Every photo-scanned or AI-generated texture has a secret problem: it's not albedo, it's albedo plus lighting. Big soft shadows, a hotspot from the capture lights, a gradient across the whole scan. Plaster that onto a 3D object and the lighting fights your scene lighting - the texture looks lit by a photographer who isn't there. x1TextureDelight is the node that separates the two: it flattens the lighting out of the texture while trying hard to keep the actual surface detail. That's the hard part, and it's what this node is built around.
How it works
The core move is simple and standard in texture pipelines: blur the image to get a "lighting" layer, then divide the detail out of it. What makes x1TextureDelight worth using over doing that by hand is how it finesses the details. blur_radius (32px, and it goes to 512) sets the scale of what counts as lighting - anything larger than that blur is lighting and gets flattened, anything smaller is surface detail and gets kept. The tension is real: blur too little and you flatten the fabric weave; blur too much and the lighting ghost sneaks back in.
flatten_strength (0.85) is how hard the lighting is actually removed, and detail_preserve (0.8) is the counter-knob - it re-injects the fine detail that the flattening would otherwise destroy. This pair is the whole game: max flatten with max preserve is the goal, and the defaults are already in the right ballpark. Then shadow_lift (0.3) and highlight_compress (0.2) handle the ends - lifting crushed shadows and compressing blown highlights so the flat result has a usable range - and saturation_restore (0.18) puts back a little color that the division knocks out.
The inputs that matter
Settings live in a settings_json string, prefilled:
blur_radius(32) - the lighting scale. The first thing you'll tune per-texture.flatten_strength(0.85) - how much lighting to remove.detail_preserve(0.8) - how much surface detail to keep.shadow_lift(0.3) /highlight_compress(0.2) - recover the ends.saturation_restore(0.18) - bring back color.mask_feather(8.0) - for the optionalmaskinput.
Outputs are image, mask, and delight_info (a text log of the settings).
Installing it
Part of the MKRShift Nodes pack. ComfyUI Manager: search "MKRShift", install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes
Restart after. No models - it's a blur-and-divide in numpy, though the blur is the one part of this pack that starts to feel it on very large textures, so it's still fast, just not instant.
Gotchas
The classic mistake is treating flatten_strength as the only knob and maxing it - you'll get a perfectly flat texture that's also perfectly dead, because you've also flattened the AO and the surface variation. Keep detail_preserve high and use mask if the scan has a subject that shouldn't be de-lit. And remember this is a pre-bake step: de-light before you multiply in your normal-derived AO, not after. Sequence it with the pack's x1TextureAlbedoSafe - delight first, then albedo-safe the result, and you have a texture a renderer won't argue with.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| settings_json | STRING | {"blur_radius":32.0,"flatten_strength":0.85,"detail_preserve":0.8,"shadow_lift":0.3,"highlight_compress":0.2,"saturation_restore":0.18,"mask_feather":8.0,"invert_mask":false} | — |
| maskopt | MASK | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| delight_info | STRING | — |