NAME
Acme::Noisemaker - Visual noise generator
VERSION
This document is for version 0.006 of Acme::Noisemaker.
SYNOPSIS;
use Acme::Noisemaker qw| make |;
Make some noise and save it as an image to the specified filename:
make(
type => $type, # white|square|perlin|complex
out => $filename, # "pattern.bmp"
#
# Any noise args or post-processing args
#
);
A wrapper script, bin/make-noise
, is included with this distribution.
bin/make-noise --type complex --out pattern.bmp
Noise sets are just 2D arrays:
use Acme::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);
#
# Insert image manip methods here!
#
$img->write(file => "oot.png");
DESCRIPTION
This module generates various types of two-dimensional grayscale noise. It is not fast, it is not a faithful implementation of any particular algorithm, and it probably never will be.
It is, possibly, a fun and/or educational toy if you are interested in procedural texture generation, or might be useful if you just want a simple module to make a few unique patterns with.
As long as the provided side length is a power of the noise's base frequency, this module will produce seamless tiles. For example, a base frequency of 2 would work fine for an image with a side length of 256 (256x256).
FUNCTIONS
make(type => $type, out => $filename, %ARGS)
my ( $grid, $img ) = make( type => "perlin", out => "perlin.bmp", # # Any noise args or post-processing args # );
Creates the specified noise type (white, square, perlin, or complex), writing the resulting image to the received filename.
Returns the resulting dataset, as well as the Imager object which was created from it.
See POST-PROCESSING FUNCTIONS for additional fun-ctionality.
make-noise
, included with this distribution, provides a CLI for this function.img($grid)
my $grid = perlin(); my $img = img($grid); # # Insert Imager image manip stuff here! # $img->write(file => "oot.png");
Returns an Imager object from the received two-dimensional grid.
clamp($value)
my $clamped = clamp($num);
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.
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).
Acme::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. Not currently used, but it's there.
http://en.wikipedia.org/wiki/Linear_interpolation
coslerp($a, $b, $x)
Cosine interpolate from $a to $b, by $x percent. $x is between 0 and 1.
POST-PROCESSING FUNCTIONS
smooth($grid)
# # Unsmoothed noise source # my $grid = white(smooth => 0); my $smooth = smooth($grid);
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);
sphere
may also be passed as an arg to tomake
.my $grid = make( type => "perlin", sphere => 1, );
refract($grid)
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);
refract
may also be passed as an arg tomake
.my $grid = make( type => "perlin", refract => 1, );
GENERATORS
Each noise function returns a two-dimentional array containing grayscale values.
All function args are optional-- the built-in defaults should be reasonable to get started with. Each noise function accepts the following args in hash key form:
amp - Amplitude, or max variance from the bias value
freq - Frequency, or "density" of the noise produced
len - Side length of the output images, which are always square
bias - "Baseline" value for all pixels, .5 = 50%
smooth - Enable/disable noise smoothing. 1 is recommended.
For the purposes of this module, amplitude actually means semi-amplitude (peak-to-peak amp/2), and frequency represents the edge length of the starting white noise grid.
...in addition, Perlin and Complex noise accept:
oct - Octave count, increases the complexity of Perlin noise
...and Complex noise has several more possible args:
feather - Edge falloff amount for Complex noise. 0-255
layers - Number of noise sources to use for Complex noise
White
my $grid = white( amp => <num>, freq => <num>, len => <int>, bias => <num>, smooth => <0|1> );
White noise, for the purposes of this module, is probably what most people think of as noise. It looks like television static-- every pixel contains a pseudo-random value.
Diamond-Square
my $grid = square( amp => <num>, freq => <num>, len => <int>, bias => <num>, smooth => <0|1> );
Sometimes called "cloud" or "plasma" noise. Often suffers from diamond- and square-shaped artifacts, but there are ways of dealing with them.
This module seeds the initial values with White noise.
Perlin
my $grid = perlin( amp => <num>, freq => <num>, len => <int>, oct => <int>, bias => <num>, smooth => <0|1> )
Perlin noise (not related to Perl) combines multiple noise sources to produce very turbulent-looking noise.
This module generates its Perlin slices from Diamond-Square noise.
Complex Perlin
my $grid = complex( amp => <num>, freq => <num>, len => <int>, oct => <int>, bias => <num>, feather => <num>, layers => <int>, smooth => <0|1> )
Complex Perlin noise combines multiple Perlin noise sources. This is not a real name for any noise type beyond this module, as far as I can tell, but the methodology used to combine the noise is heavily inspired by the way libnoise allows the daisy-chaining of different noise modules.
SEE ALSO
Acme::Noisemaker is on github: http://github.com/aayars/noisemaker
Wikipedia
As usual, Wikipedia is there for us.
Diamond-Square algorithm: http://en.wikipedia.org/wiki/Diamond-square_algorithm
Perlin Noise: http://en.wikipedia.org/wiki/Perlin_noise
White Noise: http://en.wikipedia.org/wiki/White_noise
Interpolation: http://en.wikipedia.org/wiki/Interpolation
Generating Random Fractal Terrain - http://gameprogrammer.com/fractal.html
This page has a good intro to Diamond-Square noise. It taught me how to make clouds.
Perlin Noise - http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
Acme::Noisemaker heavily pilfers the pseudo-code for interpolation and smoothing functions which I found at the above site.
libnoise - http://libnoise.sourceforge.net/
"A portable, open-source, coherent noise-generating library for C++"
Though it does not use it, Acme::Noisemaker is inspired by libnoise, which is what you should really be using if you're serious about this sort of thing. It is very cool stuff. The developer has provided many examples which let you write C++ without actually knowing it (cue Sorcerer's Apprentice music...)
pynoise - http://home.gna.org/pynoise/
Python bindings to libnoise via swig. I would like to make a package like this for Perl one day, unless someone else wants to first.
AUTHOR
Alex Ayars <pause@nodekit.org>
COPYRIGHT
File: Acme/Noisemaker.pm
Copyright (c) 2009 Alex Ayars
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://opensource.org/licenses/cpl1.0.txt