Skip to content

Flood Fill Nodes

Most procedural texturing works pixel by pixel: every operation looks at a color value and returns a new one, with no idea which brick, tile or pebble that pixel belongs to. The Flood Fill family breaks that limit. Feed it a black-and-white image and it performs connected-component labeling: it walks the image, finds every enclosed shape, and gives each one its own internal identity number. From that moment on, the rest of the family can address shapes individually. Make every brick a different color, grow each stone by a different random amount, put one rivet in the center of each cell, keep only the three biggest shapes.

The family is five nodes, meant to be used in workflow order: Flood Fill, then Region Select, then Region Modify, then Region Query or Region Scatter. Flood Fill does the analysis and nothing else. On its own it is pure data: its preview is a plain white-on-black mask of everything it labeled, not a per-region look. Everything downstream reads that one shared analysis. This matters for speed: the source image is analyzed once, no matter how many Region nodes you hang off it, so you can pull five different properties out of the same Flood Fill for the price of one.

Region data travels the wires as an ordinary texture. That is deliberate. You can plug a Region Query straight into a Blend, a Warp, a Levels or a Gradient Map, and using this data in ways it was not “meant” for is encouraged. Two practical rules to remember: all five nodes work in tiling space by default, so a shape that crosses the image edge stays a single region; and every Region node renders at the Flood Fill’s analysis resolution, which means their own per-node resolution control has no effect.

The whole family runs on the native render core. Connected-component labeling is a GPU compute pass, and both distance transforms run as a jump flood instead of the sequential chamfer sweeps they replaced, which were the slowest part of the analysis. The native path also samples the region id field and the per-region table with nearest filtering, so a pixel on a boundary reads its own region instead of an interpolation of two neighbors. Binarizing the input and computing the per-region statistics stay on the CPU deliberately, and CPU versions of the rest remain as a fallback, so a build without the core finds the same regions, only slower.

A good starting point is a Cells or Voronoi node from the Generators for instant brick, pebble or scale regions, or a thresholded Perlin/FBM for organic blobs.

Type id: flood_fill

Labels each connected region of a mask so later nodes can address them individually. This node produces data, not a picture. Its preview is a white-on-black mask of every labeled region; wire it into a Region node to see anything per-region.

Inputs: Height / Mask (texture, required), the image to analyze. It is thresholded into shape and background before labeling.

Outputs: Regions (texture), the region carrier every other Flood Fill node reads.

ParameterTypeDefaultRange / OptionsNotes
Source ChannelChoiceLuminanceLuminance, Red, Green, Blue, AlphaWhich channel of the input is thresholded.
ThresholdSlider0.50.0 to 1.0The cutoff between “shape” and “background”.
InvertToggleOffOn / OffSwaps shape and background.
ConnectivityChoice8-connected4-connected, 8-connected8-connected merges diagonally touching pixels into one region; 4-connected keeps them separate.
BackgroundChoiceExcludeExclude, Include as RegionExclude treats the below-threshold area as empty space between shapes. Include as Region also cuts the background into its own regions.
TilingToggleOnOn / OffTreats the image as seamless, so a shape crossing the edge counts as one region rather than two. Keep this on for tileable materials.
SeedSeed0Any whole numberReshuffles the per-region random values and colors baked into the analysis. Changing it re-runs the analysis; to re-roll the random maps without that, use Region Query’s own Seed.

Type id: region_select

Picks regions out of a Flood Fill (largest, smallest, by index, at random or by area) and outputs them as a white-on-black mask. Everything downstream of a Select sees only the surviving regions, so chain it before a Query or a Modify to affect just the chosen shapes.

Inputs: Regions (texture, required), a Flood Fill or another Region node carrying an analysis.

Outputs: Selection (texture), a white-on-black mask of the regions that survived the filter, plus the filtered analysis for downstream Region nodes.

ParameterTypeDefaultRange / OptionsNotes
ModeChoiceLargestAll, Largest, Smallest, Index, Index Range, Random, By AreaA new node starts on Largest with Count 1, i.e. showing only the single biggest shape.
CountInteger10 to 256How many regions to keep for Largest, Smallest and Random. In Index mode this doubles as the index of the one region to keep. Shown for Largest, Smallest, Index and Random.
Range StartInteger00 to 256First region index of the run. Shown for Index Range.
Range EndInteger40 to 256End of the run, exclusive: Start 0 / End 4 keeps regions 0, 1, 2 and 3. Shown for Index Range.
Area MinSlider0.00.0 to 1.0Lower area bound, as a fraction of the image. Shown for By Area.
Area MaxSlider1.00.0 to 1.0Upper area bound. Shown for By Area.
SeedSeed0Any whole numberWhich regions the Random mode picks. Stable for a given seed. Shown for Random.

Only the controls that matter for the current mode are shown; All has no extra controls at all.

Type id: region_modify

Grows, shrinks or softens each Flood Fill region independently, optionally by a different random amount per region. The random mode is the one that turns a regular grid of cells into hand-cut, irregular stonework.

Inputs: Regions (texture, required), the analysis to reshape.

Outputs: Regions (texture), the reshaped regions, ready for a Query, a Scatter or another Modify.

ParameterTypeDefaultRange / OptionsNotes
OperationChoiceExpandExpand, Contract, Feather, RandomExpand grows every region outward; Contract shrinks every region inward; Feather softens the silhouette into a smooth-edged mask without changing the underlying regions; Random grows or shrinks each region by its own amount.
AmountSlider0.050.0 to 0.5Distance as a fraction of the shorter image edge. For Random this is the maximum magnitude in either direction.
BiasSlider0.50.0 to 1.0Tips the Random balance: 0 = everything contracts, 0.5 = even, 1 = everything expands. Shown for Random only.
SeedSeed0Any whole numberWhich region gets which random amount. Shown for Random only.

Expand, Contract and Random move the actual region boundaries, so masks and further chaining stay correct. Feather only softens the visible edge; downstream nodes still see the original hard-edged regions. After a boundary-moving operation, area is recounted from the new labels, but centroid, bounding box and perimeter are inherited from before the change, and average color and average height cannot be refreshed at all because Region Modify does not hold the source image. A later Region Query reads those inherited numbers.

What those three ops move is the boundary between regions and background, so with the upstream Flood Fill set to Include as Region there is no background left to move into and the Amount control is hidden. Feather still works there, because it only softens the carrier.

Recipe, stone walls and cracked plates: Cells, then Flood Fill, then Region Modify set to Random with Amount around 0.1, then adjust Seed until the silhouette reads right. Follow with a Region Query in Distance to Edge for chiselled bevels.

Type id: region_query

Reads one property of the regions and outputs it as a map. This single node replaces a whole shelf of “flood fill to X” nodes; pick what you want from the Mode list. Drop several Region Query nodes on the same Flood Fill to pull different properties at once; they all share the one analysis.

Inputs: Regions (texture, required), the analysis to read.

Outputs: Output (texture), a grayscale map, a color map or a packed vector depending on the mode, deliberately typed as a generic texture so it wires into anything.

ParameterTypeDefaultRange / OptionsNotes
ModeChoiceRandom ValueRandom Value, Random Color, Average Color, Average Height, Area, Perimeter, Aspect Ratio, Region ID, Local UV, Centroid, Bounding Box, Distance to Edge, Distance to Center, Border Mask, Interior Mask, Region Count, Random SlopeWhich property to output. See the table below.
ScaleSlider1.00.0 to 8.0Widens the distance falloff and the Border/Interior margin. Shown only for Distance to Edge, Distance to Center, Border Mask and Interior Mask.
SeedSeed0Any whole numberRe-rolls Random Value, Random Color and Random Slope’s per-region direction. It is applied while the map is drawn, so scrubbing it never re-runs the Flood Fill analysis, and two Region Query nodes on one Flood Fill can carry different randomness. At 0, Random Value and Random Color keep the values the Flood Fill baked; Random Slope’s direction is seeded per region either way, since randomizing it is that mode’s own job.
Slope AngleSlider0.00.0 to 360.0Direction of the Random Slope ramp, in degrees. Shown for Random Slope.
Slope RandomSlider0.00.0 to 1.0How much of a seeded per-region turn is added to Slope Angle. 0 points every region the same way, 1 gives every region its own direction. Shown for Random Slope.

Modes, in list order:

ModeWhat it outputs
Random ValueEach region a flat random gray. The classic flood-fill look; drive roughness or height variation with it.
Random ColorEach region a flat random color.
Average ColorEach region filled with the average color of the input underneath it.
Average HeightEach region filled with the average brightness of the input underneath it.
AreaBrighter = larger region, as a fraction of the image.
PerimeterA rough “how convoluted is the outline” value per region.
Aspect RatioSquare regions read black, long thin ones read white (1:1 reads 0, 8:1 reads 1).
Region IDA ramp from the first region to the last; useful as a mask source or gradient index.
Local UVA 0 to 1 gradient across each region’s bounding box, packed into Red and Green. Feed it a warp or gradient for per-region effects.
CentroidEach region flat-filled with its center position (Red = x, Green = y).
Bounding BoxEach region’s box packed as Red/Green/Blue/Alpha = min x, min y, max x, max y.
Distance to Edge0 at the region edge, rising toward the center. Great for bevels and inset masks.
Distance to Center0 at the centroid, rising toward the edges.
Border MaskA band hugging each region’s outline, on both sides of the boundary.
Interior MaskThe inside of each region, past a margin.
Region CountA single flat gray encoding how many regions were found (value is roughly the count divided by 256). It covers the whole image, background included.
Random SlopeA grayscale ramp across each region’s bounding box, running 0 to 1 along Slope Angle. Feed it to Height Blend or Normal from Height for tilted tiles, stone steps and torn shingles.

Region Count fills the whole image, and Border Mask’s band covers the background side of each boundary as well as the inside. Every other mode leaves the background black.

Recipes: per-brick color is Cells, Flood Fill, then Region Query in Random Color. Worn tile heights are Flood Fill, Region Query in Random Value, then Levels, blended over your base height. Bevelled edges are Region Query in Distance to Edge into Levels or Curves. Two Region Query nodes on one Flood Fill with different Seeds give two uncorrelated random maps, one for roughness and one for color, without a second analysis.

Type id: region_scatter

Places one copy of a stamp per region, positioned and sized to fill each region’s footprint rather than clipped to the blob shape, so it reads as a positioned instance instead of a mask. Each region owns a territory, so stamps do not overlap. The result sits on a transparent background; put a Blend after it to composite over a base.

Inputs: Regions (texture, required), the analysis that decides where stamps land. Stamp (texture, required), the thing to place: a Shape, an imported image, or any sub-graph.

Outputs: Output (texture), the stamps, one per region, on transparency.

ParameterTypeDefaultRange / OptionsNotes
ScaleSlider1.00.0 to 4.0Stamp size relative to each region’s box.
Scale RandomSlider0.00.0 to 1.0Per-region random size variation.
RotationSlider0.0-180.0 to 180.0Base rotation, in degrees.
Rotation RandomSlider0.00.0 to 1.0Per-region random spin on top of the base rotation.
SeedSeed0Any whole numberReshuffles the random scale and rotation.

Tip: feed a Shape (circle or hex) as the stamp to drop one shape per cell. Studs on a plate, rivets, pebbles.