The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Math::Fractal::Noisemaker - Visual noise generator

VERSION

This document is for version 0.015 of Math::Fractal::Noisemaker.

SYNOPSIS

  use Math::Fractal::Noisemaker qw| :all |;

  #
  # use defaults
  #
  make();

  #
  # override defaults
  #
  make(type => 'gel',
    # ...
  );

A wrapper script, make-noise, is included with this distribution.

  #
  # use defaults
  #
  make-noise

  #
  # override defaults
  #
  make-noise -type gel

  #
  # usage
  #
  make-noise -help

  make-noise -help types

Noise sets are just 2D arrays, which may be generated directly using named functions.

  use Math::Fractal::Noisemaker qw| :flavors |;

  my $grid = square(%args);

  #
  # Look up a value, given X and Y coords
  #
  my $value = $grid->[$x]->[$y];

Imager can take care of further post-processing.

  my $grid = perlin(%args);

  my $img = img($grid,%args);

  #
  # Insert image manip methods here!
  #

  $img->write(file => "oot.png");

DESCRIPTION

Math::Fractal::Noisemaker provides a simple functional interface for generating 2D fractal (or non-fractal) noise.

If the specified side length is a power of the noise's frequency, this module will produce seamless tiles (with the exception of a few noise types). For example, a base frequency of 4 works for an image with a side length of 256 (256x256).

FUNCTION

  • make(type => $type, out => $filename, %ARGS)

      #
      # Just make some noise:
      #
      make();
    
      #
      # Care slightly more:
      #
      my ( $grid, $img, $filename ) = make(
        #
        # Any MAKE ARGS or noise args here!
        #
      );

Creates the specified noise type (see NOISE TYPES), writing the resulting image to the received filename.

Unless seriously tinkering, make may be the only function you need. make-noise, included with this distribution, provides a CLI for this function.

Returns the resulting dataset, as well as the Imager object which was created from it and filename used.

MAKE ARGS

In addition to any argument appropriate to the type of noise being generated, make accepts the following args in hash key form:

  • type => $noiseType

    The type of noise to generate, defaults to perlin. Specify any type.

      make(type => 'gel');
  • sphere => $bool

    sphere example

    Generate a pseudo-spheremap from the resulting noise.

    When specifying sphere, the output image will be 50% of the len you asked for. This is done to avoid aliasing. Multiply the supplied len argument by 2 to work around this.

    See spheremap.

      make(sphere => 1);
  • refract => $bool

    refract example

    "Refracted" pixel values. Can be used to enhance the fractal appearance of the resulting noise. Often makes it look dirty.

      make(refract => 1);
  • clut => $filename

    Use an input image as a color lookup table

    This feature is a work in progress.

      make(clut => $filename);
  • clutdir => <0|1|2>

    0: Hypotenuse lookup (corner to corner, so it doesn't matter if the input table is oriented horizontally or vertically).

    clutdir 0 example

    This is the default. Best for seamless tiling.

      make(clut => $filename, clutdir => 0);

    1: Vertical lookup, good for generating maps which have ice caps at the poles and tropical looking colors at the equator.

    clutdir 1 example

    Output will have color seams at the poles unless viewed on a spheroid. This lookup method produces output which resembles a reflection map, if a photograph is used for the clut.

      make(clut => $filename, clutdir => 1);

    2: Fractal lookup, uses the same methodology as refract. Also good for seamless tiling.

    clutdir 2 example

      make(clut => $filename, clutdir => 2);
  • limit => <0|1>

    0: Scale the pixel values of the noise set to image-friendly levels

    1: Clamp pixel values outside of a representable range

      make(limit => 1);
  • quiet => <0|1>

    Don't spam console

      make(quiet => 1);
  • out => $filename

    Output image filename. Defaults to the name of the noise type being generated.

      make(out => "oot.bmp");
  • shadow => $float

    shadow example

    Amount of self-shadowing to apply, between 0 and 1.

  • emboss => <0|1>

    emboss example

    Render lightmap only

NOISE TYPES

SINGLE-RES NOISE

Single-res noise types may be specified as a multi-res slice types (stype)

  • white

    white noise example

    Each non-smoothed pixel contains a pseudo-random value.

    See SINGLE-RES ARGS for allowed arguments.

  • wavelet

    wavelet noise example

    Basis function for sharper multi-res slices

    See SINGLE-RES ARGS for allowed arguments.

  • square

    square noise example

    Diamond-Square (mostly square)

    See SINGLE-RES ARGS for allowed arguments.

  • gel

    gel noise example

    Self-displaced white noise.

    See SINGLE-RES ARGS and GEL TYPES for allowed arguments.

  • sgel

    square gel noise example

    Self-displaced Diamond-Square noise.

    See SINGLE-RES ARGS and GEL TYPES for allowed arguments.

  • dla

    diffusion-limited aggregation noise example

    Diffusion-limited aggregation, seeded from multiple random points.

    See SINGLE-RES ARGS for allowed arguments.

    bias and amp currently have no effect.

  • mandel

    mandelbrot fractal example

    Fractal type - Mandelbrot. Included as a demo.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    Example maxiter value: 256

  • dmandel

    deep mandelbrot fractal example

    Fractal type - Deep Mandelbrot. Picks a random "interesting" location in the set (some point with a value which neither hovers near 0 nor flies off into infinity), and zooms in a random amount (unless an explicit zoom arg was provided).

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    Example maxiter value: 256

  • buddha

    buddhabrot fractal example

    Fractal type - "Buddhabrot" Mandelbrot variant. Shows the paths of slowly escaping points, density-mapped to escape time.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect. This type does not zoom well, due to the diminished sample of escaping points.

    Example maxiter value: 4096

  • julia

    julia fractal example

    Fractal type - Julia. Included as demo.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    zoom is not yet implemented for this type.

    Example maxiter value: 200

  • djulia

    deep julia fractal example

    Fractal type - Deep Julia. Zoomed in to a random location, which might not even be in the Julia set at all. Not currently very smart, but pretty, and pretty slow. maxiter is very low by default.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    zoom is not yet implemented for this type.

    Example maxiter value: 200

  • newton

    newton fractal example

    Fractal type - Newton. Included as demo.

    Currently, this function is ridiculously slow.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    zoom is not yet implemented for this type.

    Example maxiter value: 10

  • fflame

    ifs fractal flame example

    IFS type - "Fractal Flame". Work in progress. Slow but neat.

    See SINGLE-RES ARGS and FRACTAL ARGS for allowed arguments.

    bias and amp currently have no effect.

    Example maxiter value: 6553600

  • fern

    fern example

    IFS type - Barnsley's fern. Included as a demo.

  • gasket

    gasket example

    IFS type - Sierpinski's triangle/gasket. Included as a demo.

  • stars

    stars example

    White noise generated with extreme gap, and smoothed

    See SINGLE-RES ARGS for allowed arguments.

    bias and amp currently have no effect.

  • spirals

    spirals example

    Tiny logarithmic spirals

    See SINGLE-RES ARGS for allowed arguments.

    bias and amp currently have no effect.

  • voronoi

    voronoi example

    Ridged Voronoi cells.

    bias and amp currently have no effect.

  • moire

    moire example

    Interference pattern with blended image seams.

    Appearance of output is heavily influenced by the freq arg.

    bias and amp currently have no effect.

  • textile

    textile example

    Moire noise with a randomized and large freq arg.

    bias and amp currently have no effect.

  • infile

    Import the brightness values from the file specified by the "in" or "-in" arg.

      my $grid = infile(
        in => "dirt.bmp"
      );
  • intile

    intile example

    Calls infile, and makes a seamless repeating tile from the image.

      my $grid = intile(
        in => "dirt.bmp"
      );
  • sparkle

    sparkle example

    Stylized starfield

    bias and amp currently have no effect.

  • brownian

    brownian example

    Fractional Brownian noise (via Math::Random::Brownian)

    bias currently has no effect.

  • gaussian

    gaussian example

    Fractional Gaussian noise (via Math::Random::Brownian)

    bias currently has no effect.

SINGLE-RES ARGS

Single-res noise types accept the following arguments in hash key form:

  • amp => <0..1>

    Amplitude, or max variance from the bias value.

    For the purposes of this module, amplitude actually means semi- amplitude (peak-to-peak amp/2).

      make(amp => 1);
  • freq => $int

    Frequency, or "density" of the noise produced.

    For the purposes of this module, frequency represents the edge length of the starting noise grid.

      make(freq => 8);
  • len => $int

    Side length of the output images, which are always square.

      make(len => 512);
  • bias => <0..1>

    "Baseline" value for all pixels, .5 = 50%

      make(bias => .25);
  • smooth => <0|1>

    Enable/disable noise smoothing. 1 is default/recommended

      make(smooth => 0);
  • gap => <0..1>

    Larger values increase the chance for black pixels in white noise (which many noise types are derived from).

      make(type => "white", gap => .995);

FRACTAL ARGS

  • zoom => $num

    Magnifaction factor.

      make(type => 'mandel', zoom => 2);
  • maxiter => $int

    Iteration limit for determining infinite boundaries, larger values take longer but are more accurate/look nicer.

      make(type => 'mandel', maxiter => 2000);

MULTI-RES TYPES

Perlin (multi-res) noise combines the values from multiple 2D slices (octaves), which are generated using successively higher frequencies and lower amplitudes.

The slice type used for generating multi-res noise may be controlled with the stype argument. Any single-res type may be specified.

The default slice type is smoothed wavelet noise.

  • perlin

    perlin example

    Multi-resolution noise.

    See MULTI-RES ARGS for allowed args.

      make(type => 'perlin', stype => '...');
  • ridged

    ridged example

    Ridged multifractal.

    See MULTI-RES ARGS for allowed args.

    Provide zshift arg to specify a post-processing bias.

      make(type => 'ridged', stype => '...', zshift => .5 );
  • block

    block example

    Unsmoothed multi-resolution.

    See MULTI-RES ARGS for allowed args.

      make(type => 'block', stype => ...);
  • pgel

    perlin gel example

    Self-displaced multi-res noise.

    See MULTI-RES ARGS and GEL TYPES for allowed args.

      make(type => 'pgel', stype => ...);
  • fur

    fur example

    Fur-lin noise; traced paths of worms with multi-res input.

    See MULTI-RES ARGS for allowed args.

  • tesla

    tesla example

    Long, fiberous worm paths with random skew.

    See MULTI-RES ARGS for allowed args.

  • lumber

    lumber example

    Persistent noise with heavy banding.

    Looks vaguely wood-like with the right clut.

    See MULTI-RES ARGS for allowed args.

  • wormhole

    wormhole example

    Noise values displaced according to field flow rules, and plotted.

    amp controls displacement amount (eg 8).

    See MULTI-RES ARGS for allowed args.

  • flux

    flux example

    Noise values extruded in three dimensions, and plotted.

    amp controls extrusion amount (eg 8).

    See MULTI-RES ARGS for allowed args.

MULTI-RES ARGS

In addition to any of the args which may be used for single-res noise types, Perlin noise types accept the following arguments in hash key form:

  • octaves => $int

    e.g. 1..8

    Octave (slice) count, increases the complexity of Perlin noise. Higher generally looks nicer.

      my $blurry = make(octaves => 3);
    
      my $sharp = make(octaves => 8);
  • persist => $num

    Per-octave amplitude multiplicand (persistence). Traditional and default value is .5

      my $grid => make(persist => .25);
  • stype => $simpleType

    Perlin slice type, defaults to wavelet. Any single-res type may be specified.

      my $grid = make(stype => 'gel');

DUAL NOISE

Dual noise contains two noise sets of the same type.

  • delta

    delta example

    Difference noise; output contains absolute values of subtracting two noise sets.

      make( type => "delta" );

    Use ltype to specify any single-res or perlin layer type. If specifying a perlin layer type, you may also specify stype to override the slice type.

      make(
        type => "delta",
        ltype => "gel"
      );
  • chiral

    chiral example

    Twin noise; output contains the lightest values of two noise sets.

      make( type => "chiral" );

    Use ltype to specify any single-res or perlin layer type. If specifying a perlin layer type, you may also specify stype to override the slice type.

      make(
        type => "chiral",
        ltype => "tesla"
      );
  • stereo

    stereo example

    Stereoscopic depth map.

    Use ltype to specify any single-res or perlin layer type. If specifying a perlin layer type, you may also specify stype to override the slice type.

COMPLEX NOISE

Complex noise is a homebrew noise recipe inspired by (but not using) libnoise.

  • complex

    complex example

    Complex layered noise

      make(type => "complex");

    This function generates a noise base and multiple noise layers. Each pixel in the resulting noise is blended towards the value in the noise layer which corresponds to the reference value in the noise base. Finally, the noise base itself is very slightly superimposed over the combined layers.

      my $grid = complex();

    Hundreds of noise variants (many of them quite interesting visually) may be generated through this function, by combining different base types, layer types, and slice types.

      my $grid = complex(
        lbase => <any noise type but complex>,
        ltype => <any noise type but complex>,
        stype => <any single-res type>,
        # ...
      );

In addition to all single-res and Perlin args, complex noise accepts the following args in hash key form:

  • feather => $num

    e.g. 0..255

    Amount of blending between different regions of the noise.

      make(type => 'complex', feather => 50);
  • layers => $int

    Number of complex layers to generate

      make(type => 'complex', layers => 4);
  • lbase => $noiseType

    Complex layer base - defaults to "perlin". Any type except for complex may be used.

      make(type => 'complex', lbase => 'gel');
  • ltype => $noiseType

    Complex layer type - defaults to "perlin". Any type except for complex may be used.

      make(type => 'complex', ltype => 'gel');

GEL TYPES

The single-res and Perlin "gel" types (gel, sgel, pgel) accept the following additional arguments:

  • displace => $float

    Amount of self-displacement to apply to gel noise

      make(type => 'gel', displace => .125);

MORE FUNCTIONS

  • img($grid,%args)

      my $grid = perlin();
    
      my $img = img($grid,%args);
    
      #
      # Insert Imager image manip stuff here!
      #
    
      $img->write(file => "oot.png");

    Returns an Imager object from the received two-dimensional grid.

  • clamp($value)

    Limits the received value to between 0 and 255. If the received value is less than 0, returns 0; more than 255, returns 255; otherwise returns the same value which was received.

      my $clamped = clamp($num);
  • noise($grid, $x, $y)

    The so-called "noise function" required to generate coherent noise. Returns the same "random" value each time it is called with the same arguments (makes it more like a key hashing function a la memcached doesn't it? Not very random, if you ask me).

    Math::Fractal::Noisemaker diverges from most Perlin implementations in that its noise function simply utilizes a lookup table. The lookup table contains pre-populated random values. Turns out, this works fine.

  • lerp($a, $b, $x)

    Linear interpolate from $a to $b, by $x percent. $x is between 0 and 1.

  • coslerp($a, $b, $x)

    Cosine interpolate from $a to $b, by $x percent. $x is between 0 and 1.

  • smooth($grid, %args)

      #
      # Unsmoothed noise source
      #
      my $grid = white(smooth => 0);
    
      my $smooth = smooth($grid,%args);

    Perform smoothing of the values contained in the received two-dimensional grid. Returns a new grid.

    Smoothing is on by default.

  • spheremap($grid, %args)

    Generates a fake (but convincing) spheremap from the received 2D noise grid, by embellishing the polar regions.

    Re-maps the pixel values along the north and south edges of the source image using polar coordinates, slowly blending back into original pixel values towards the middle.

    Returns a new 2D grid of pixel values.

      my $grid = perlin(%args);
    
      my $spheremap = spheremap($grid,%args);

    See MAKE ARGS

  • refract($grid,%args)

    Return a new grid, replacing the color values in the received grid with one-dimensional indexed noise values from itself. This can enhance the "fractal" appearance of noise.

      my $grid = perlin(%args);
    
      my $refracted = refract($grid);

    See MAKE ARGS

  • displace($grid,%args)

    Use the received grid as its own displacement map; returns a new grid.

    The amount of displacement is controlled by the displace arg.

    See GEL TYPES

SEE ALSO

Imager, Math::Trig

Math::Fractal::Noisemaker is on GitHub: http://github.com/aayars/noisemaker

Noisemaker borrows inspiration and/or pseudocode from these notable sources.

  - http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
    Perlin

  - http://gameprogrammer.com/fractal.html
    Diamond-Square

  - http://graphics.pixar.com/library/WaveletNoise/paper.pdf
    Wavelet (Pixar)

  - http://www.complang.tuwien.ac.at/schani/mathmap/stills.html
    Moire (MathMap)

  - http://libnoise.sourceforge.net/
    Libnoise is pro

  - http://flam3.com/flame.pdf
    Fractal Flame

  - http://en.wikipedia.org/wiki/File:Demj.jpg
    C<julia> and C<jdist> functions ported from "Julia set using
    DEM/J" by Adam Majewski

  - http://vlab.infotech.monash.edu.au/simulations/fractals/
    C<newton> function ported from "Fractals on the Complex Plane"

... and a host of others.

AUTHOR

  Alex Ayars <pause@nodekit.org>

COPYRIGHT

  File: Math/Fractal/Noisemaker.pm
 
  Copyright (C) 2009, Alex Ayars <pause@nodekit.org>

  This program is free software; you can redistribute it and/or modify
  it under the same terms as Perl 5.10.0 or later. See:
  http://dev.perl.org/licenses/