Nodes/ComfyUI-QuasimondoNodes/Perlin Noise Generator
ComfyUI Node

Perlin Noise Generator

Gradient noise that looks like terrain, not TV static

By Quasimondo·Created 2 years ago·Updated about a year ago· 15
Perlin Noise Generator
    • IMAGE
    • image_count
    • width
    • height
    image_count1
    width512
    height512
    channels
    random_seed0
    octaves3
    res8
    persistence0.500
    phase0.000
    normalizetrue

    If you've ever needed a mask that looks like clouds, a height map that looks like terrain, or a displacement texture with coherent organic shape, you want Perlin noise - the smooth gradient noise from Ken Perlin's 1983 SIGGRAPH paper that became the default "make it look natural" primitive in graphics. Perlin Noise Generator is a clean, seeded implementation wrapped as a node, with the two controls that actually matter (grid resolution and octaves) front and center.

    It sits in this pack's noise family next to Random Image Generator (pure random static) and Image Noise Generator (scrambles an existing image). This is the one you reach for when you want structure: blobby, cloud-like, terrain-like noise rather than pixels-with-static.

    How it works

    It's classic fBm (fractal Brownian motion). The core generates a lattice of random gradients at a base grid size - res - and interpolates between them with a smoothstep fade, producing one octave of smooth noise. Then it stacks octaves: each octave doubles the frequency (finer detail) and scales its amplitude by persistence, and the layers sum. Three octaves at persistence 0.5 gives you the familiar "clouds with detail on top of the bumps" look. A phase parameter rotates the gradient angles, which is a cheap way to shift the pattern without a new seed.

    The implementation is the well-known rand_perlin_2d recipe with smoothstep fading, seeded via torch's generator so a given random_seed reproduces the same field exactly. One implementation detail worth knowing: octaves is auto-clamped to log2(min(width, height)) - 2, so on a 512px image you physically cannot get more than ~7 octaves no matter what you type - the detail budget just isn't there.

    The inputs that matter

    • image_count - how many noise images to generate in the batch.
    • width / height - up to 8192.
    • channels - RGB, RGBA, RGB (grey), or Mask. Mask gives a single-channel output that plugs straight into mask inputs; RGB (grey) gives you the same grayscale field tripled into RGB.
    • random_seed - the field's identity.
    • octaves - detail layers (default 3, and remember the auto-clamp).
    • res - the base grid size (default 8). Lower = bigger, blobbier features; higher = finer, busier texture. This is the "wavelength" dial.
    • persistence - how much each octave adds (default 0.5). Higher = rougher, more high-frequency energy.
    • phase - a rotation of the gradient angles, a shift-without-reseed.
    • normalize - default on, stretches the output to fill 0–1.

    Outputs are the IMAGE plus image_count, width, height as ints - handy if downstream nodes want those values as numbers rather than hard-coded.

    Install

    From the Quasimondo pack. ComfyUI Manager → search ComfyUI-QuasimondoNodes, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Quasimondo/ComfyUI-QuasimondoNodes
    cd ComfyUI-QuasimondoNodes
    pip install -r requirements.txt
    

    Pure torch/numpy. No models, no downloads.

    Where people get burned

    The res vs octaves confusion is the classic. res sets the base feature size; octaves adds detail on top. Cranking octaves while leaving res at 8 just adds finer grain over big blobs - if you want more structure, raise res. And because octaves auto-clamp on small images, entering 13 octaves at 512px does nothing beyond 7; drop to a larger canvas if you genuinely need more detail layers.

    Second, normalize being on by default is usually what you want - but it stretches each channel to 0–1 per image, so if you're generating a batch and need consistent relative brightness across frames (for a temporal mask, say), you may want normalize off and to control range yourself. And a minor gotcha: at high image_count × high resolution this is a pure Python/torch loop per channel, so it's not instant at the extremes - keep res modest for large batches.

    Categoryimage/generators

    Inputs (10)

    NameTypeDefaultDescription
    image_countINT11–9007199254740991
    widthINT5121–8192
    heightINT5121–8192
    channelsCOMBO4 options: RGB, RGBA, RGB (grey), Mask
    random_seedINT00–9007199254740991
    octavesINT31–13
    resINT81–64
    persistenceFLOAT0.5000–2
    phaseFLOAT0.0000–1
    normalizeBOOLEANtrue

    Outputs (4)

    NameTypeDescription
    IMAGEIMAGE
    image_countINT
    widthINT
    heightINT