Rescale the layer to have given max and min values v5.1.0
The linear level-stretch utility
- layer_as_mask
- rescaled layer as MASK
Masks and depth-like layers arrive on all sorts of brightness scales, and half the time you need them on a different one. This node is a linear level-stretch: it maps a range of input values (x1–x2) onto a target range (y1–y2) and clips everything outside. Think of it as the "levels" tool from a photo editor, applied to a single-channel layer.
The use case that keeps coming back: a mask that only occupies values 40–200 needs to be full-range for a model that expects 0–255; or you want to squash a depth layer into a narrow band so it reads as a subtle lighting layer. It's a tiny, composable utility - the pack's own recolor and renormalize nodes assume well-distributed inputs, and this is the tool that makes them well-distributed.
How it works
Pure linear remap. The input layer is converted to float, and every pixel goes through:
y = ((x - x1) / (x2 - x1)) * (y2 - y1) + y1
then everything is clipped to [y1, y2]. The node defensively swaps x1/x2 and y1/y2 if you feed them inverted, so a descending range doesn't break - nice touch. If x2 - x1 is zero it adds a tiny epsilon to avoid dividing by zero. The result comes back as a MASK.
It pairs naturally with the pack's tri3d-get_histogram_limits, which computes x1/x2 automatically by walking the layer's histogram and trimming the tails past a threshold_fraction - so you can drive this node's input range from the data instead of eyeballing it.
The inputs that matter
layer_as_mask(MASK) - the layer to stretch.y1/y2(INT, 0–255) - the target output range. Defaults are 100 and 200.x1/x2(INT, 0–255) - the input range you're mapping from (the current spread of your values). Defaults 100 and 200.
Output: rescaled layer as MASK.
Installing it
Same pack:
cd ComfyUI/custom_nodes
git clone https://github.com/TRI3D-LC/tri3d-comfyui-nodes
cd tri3d-comfyui-nodes
pip install -r requirements.txt
or ComfyUI Manager → "tri3d-comfyui-nodes", restart, under TRI3D.
Common issues
- Ignoring the actual input range - the defaults (100–200) are placeholders, not detected values. If your layer's values live elsewhere, the stretch will crush or clip them. Either read the histogram or use
get_histogram_limitsto feed real numbers. - Clipping is silent - values below
x1and abovex2get clamped toy1/y2, so heavy stretches lose information. If edges look posterized, widen the input range. - It stretches linearly only - no gamma, no curves. For a curve-shaped remap you'd want a different node; this one is deliberately dumb.
For a "make this layer live in this range" job, it's the smallest honest tool in the pack - no pretensions, no surprises, and it composes cleanly with the nodes around it.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| layer_as_mask | MASK | — | |
| y1 | INT | 1000–255 | — |
| y2 | INT | 2000–255 | — |
| x1 | INT | 1000–255 | — |
| x2 | INT | 2000–255 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| rescaled layer as MASK | MASK | — |