Nodes/MKRShift_Nodes/Texture Macro Variation
ComfyUI Node

Texture Macro Variation

Kill the flat, repeated look — add macro variation to a texture

By criskb·Created 7 months ago·Updated 5 months ago· 0
Texture Macro Variation
  • image
  • mask
  • image
  • mask
  • macro_variation_info
settings_json{"macro_scale_px":160.0,"strength":0.55,"hue_variation":0.02,"saturation_variation":0.12,"value_variation":0.12,"contrast_variation":0.18,"seed":11,"mask_feather":8.0,"invert_mask":false}

The thing that makes a tiled texture look fake is uniformity - same tone, same saturation, same value, copy after copy after copy. Real surfaces drift: one patch is slightly darker, another is a touch warmer, the contrast changes as you move across the material. Texture Macro Variation adds exactly that: a slow, large-scale variation in hue, saturation, value, and contrast across your texture, so repeats stop reading as identical stamps. If your tileable texture looks "too clean," this is the node that fixes it without you hand-painting variation in a 3D editor.

How it works

The core is a large-scale noise field (macro_scale_px, default 160) that modulates your image in HSV space rather than RGB, which is what keeps the variation looking photographic instead of like a lighting gradient. Each of the variation channels is independent: hue_variation rotates hue subtly, saturation_variation and value_variation shift saturation and brightness, and contrast_variation modulates local contrast. strength (0.55 default) is the master mix - how strongly all of that applies. Because the modulation field is the same wrapped noise the pack's generators use, the variation is seamless too, so it doesn't introduce its own tile seam. The seed controls which patches vary where.

The optional mask limits the effect to a region, with mask_feather and invert_mask as the usual controls. The node also emits a mask showing where variation was applied, which is handy for debugging "why did this patch change."

The inputs that matter

Inputs: image, one settings_json box, optional mask. The knobs you'll actually set:

  • strength - master intensity
  • macro_scale_px - how large the variation patches are (bigger = more global drift)
  • saturation_variation / value_variation - the two that read most as "material," start here
  • seed - different variation layout

Outputs: image (the varied texture), mask (application mask), and macro_variation_info with resolved settings.

Installing it

Ships in MKRShift Nodes from criskb. ComfyUI Manager → "MKRShift Nodes", or:

cd ComfyUI/custom_nodes
git clone https://github.com/criskb/MKRShift_Nodes

Restart ComfyUI; it's under MKRShift Nodes → Surface → Texture. No models or extra deps - numpy/Pillow/torch.

Common gotchas

New pack, no community lore, so the code is ground truth. Standard MKRShift traps: broken settings_json silently reverts to defaults, out-of-range values clamp. The practical gotcha is subtlety: this node's default strength is 0.55 with value variation at 0.12, which is already noticeable on flat textures - for photoreal material work you'll often want to drop strength to 0.3 or below, because the human eye reads value variation faster than any other channel. Also remember hue variation is capped at 0.25 by design; if you're trying to push big color shifts, this isn't the tool - that's a color-grading job, not texture variation.

CategoryMKRShift Nodes/Surface/Texture

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
settings_jsonSTRING{"macro_scale_px":160.0,"strength":0.55,"hue_variation":0.02,"saturation_variation":0.12,"value_variation":0.12,"contrast_variation":0.18,"seed":11,"mask_feather":8.0,"invert_mask":false}
maskoptMASK

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
macro_variation_infoSTRING