Nodes//Whisker: Random Cube Grid Generator
ComfyUI Node

Whisker: Random Cube Grid Generator

Random cube grids — with the coordinates as JSON you can actually act on

By nerdywhiskers·Created 5 months ago·Updated a day ago· 1
Whisker: Random Cube Grid Generator
    • cube_image
    • cube_coordinates
    grid_width10
    grid_height5
    output_resolution512
    min_cube_size0.5
    max_cube_size1.0
    first_col_start_row3
    first_col_end_row7
    last_col_start_row2
    last_col_end_row8
    min_col_gap1
    max_col_gap3
    min_row_gap1
    max_row_gap3
    density0.50
    first_last_density_toggle
    seed-1

    A procedural white-on-black grid of squares is a five-minute numpy script, so the thing that makes RandomCubeGrid worth installing is not the image. It's the second output. Alongside the rendered cube_image it emits a JSON string of {x, y, size} coordinates for every cube it placed - which is what turns a pretty pattern into something a downstream node can actually build on.

    Where's that useful? Any workflow where you need cube positions and the visual: game-tile layouts, pixel-art composition frames, puzzle or shelf arrangements, or feeding coordinates into a "block grid"-style generator you're wiring up yourself. The README pitches it exactly that way - the JSON is designed to pair with downstream generator nodes, not to sit there looking pretty.

    How it works

    You give it a grid in units (grid_width × grid_height), and it places white squares at random spots with per-row and per-column gaps chosen randomly between min_*_gap and max_*_gap. Each cube's size is a random fraction of the grid unit, between min_cube_size and max_cube_size. density is the probability a given slot gets a cube at all. output_resolution sets the longest side in pixels and the other side follows the grid's aspect ratio.

    The genuinely clever part is the edge handling. first_col_start_row/first_col_end_row and last_col_start_row/last_col_end_row constrain where cubes can appear in the first and last columns, so you can frame the grid - a top border, a bottom border, whatever you need. The first_last_density_toggle decides whether density and gap randomness apply to those edge columns too, or whether they're forced to fill completely.

    The inputs that actually matter

    • seed - -1 means randomize every run; set a positive number to lock the layout.
    • density - 0 to 1. Low values scatter a few cubes; 0.5 default fills about half the slots.
    • min_cube_size / max_cube_size - cube size in grid units. Equal values give you a uniform grid of equal squares; a spread gives you the organic "random cube" look.
    • output_resolution - the longest side in pixels. This is also your quality lever: cubes are just rectangles of solid white, so the practical limit is how big you need the sheet.

    The gotcha that will bite you

    cube_coordinates is a STRING, not a list - it's a JSON array serialized as text. ComfyUI won't let you wire a string into a node expecting a list. You'll need a text/JSON viewer node (ShowText and friends) to read it, or a JSON-parsing node to convert it into a structure another custom node can consume. Figure that out before you build the workflow around the coordinates, not after.

    Both outputs are always produced - cube_image (a 3-channel IMAGE, white on black) and cube_coordinates.

    Installing it

    It ships in the Whisker pack:

    cd ComfyUI/custom_nodes
    git clone https://github.com/nerdywhiskers/ComfyUI-Whisker-Nodes.git
    pip install -r ComfyUI-Whisker-Nodes/requirements.txt
    

    or search "ComfyUI-Whisker-Nodes" in ComfyUI Manager and restart. It's under Add Node → whisker-nodes. No models, no downloads, no hidden dependencies - this one runs on numpy and torch alone. If your first result feels off, the odds are the seed or density, not the node.

    Categorywhisker-nodes

    Inputs (16)

    NameTypeDefaultDescription
    grid_widthINT101–100
    grid_heightINT51–100
    output_resolutionINT51264–4096
    min_cube_sizeFLOAT0.50.1–1
    max_cube_sizeFLOAT1.00.1–1
    first_col_start_rowINT30–100
    first_col_end_rowINT70–100
    last_col_start_rowINT20–100
    last_col_end_rowINT80–100
    min_col_gapINT10–10
    max_col_gapINT31–10
    min_row_gapINT10–10
    max_row_gapINT31–10
    densityFLOAT0.500–1
    first_last_density_toggleCOMBO2 options: enabled, disabled
    seedINT-1-1–999999

    Outputs (2)

    NameTypeDescription
    cube_imageIMAGE
    cube_coordinatesSTRING