Actionscript 3 – Better perlinNoise (perlinNoise complexification)

actionscript 3, advanced image editing, BitmapData, perlinNoise, voxels

Ok, here we are… once again speaking about perlinNoise.

PerlinNoise is a super-cool function… nothing to object, it gives you the ability to render a smooth random varying surface on a bitmapdata.

You can use it for random behaviours, for mountains generation, for lots lots of stuff resembling the inner and deep variations hidden in nature… but lets say it: it’s kinda boring to look at.

Tired to have always the same old plain smooth boring perlinNoise? Try this simple variation.



Test interactive demo #1

The main concept is EXTREMELY simple and is a trick I inherited from photoshop “Render clouds / Render difference clouds” filters.

The logic is this:

  1. Apply a simple perlinNoise method to a bitmapData
  2. For i=0 to i=N…
  3. Apply a simple perlinNoise method to a second bitmapData with a different seed at every iteration
  4. Composite the second bitmapData onto the first with the draw() method and a BlendMode.DIFFERENCE blend mode.

Look at the simple code:

var bd:BitmapData=new BitmapData(500, 300, false, 0x808080);
var bd2:BitmapData=new BitmapData(500, 300, false, 0x808080);

var bmp:Bitmap=new Bitmap(bd);
addChild(bmp);

var seed:uint;

for(var i:uint=0; i<30; i++) {
	seed=Math.random()*1000;
	bd2.perlinNoise(150, 150, 3, seed, true, true, 7, true);
	bd.draw(bd2, null, null, BlendMode.DIFFERENCE);
}

et voilĂ ! The main trick is already done.

Here the code of the above demo:

var bd:BitmapData=new BitmapData(500, 300, false, 0x808080);
var bd2:BitmapData=new BitmapData(500, 300, false, 0x808080);

var bmp:Bitmap=new Bitmap(bd);
addChild(bmp);

var isProcessing:Boolean=true;
var baseSize:uint=150;
var octaves:uint=3;
var seed:uint=50;
bd.perlinNoise(baseSize, baseSize, octaves, seed, true, true, 7, true);

stage.addEventListener(MouseEvent.CLICK, toggleProcessing);
function addLayer(event:Event):void {
	seed=Math.random()*1000;
	bd2.perlinNoise(baseSize, baseSize, octaves, seed, true, true, 7, true);
	bd.draw(bd2, null, null, BlendMode.DIFFERENCE);
}
function toggleProcessing(event:MouseEvent):void {
	isProcessing ? stage.removeEventListener(Event.ENTER_FRAME, addLayer) : stage.addEventListener(Event.ENTER_FRAME, addLayer);
	isProcessing=!isProcessing;
}

Then you can even randomize baseX and baseY size of the perlinNoise method at every iteration and have results like this:

Test interactive demo #2

And you have got the definitive grunge background generator! :D

Here comes the code:

var bd:BitmapData=new BitmapData(500, 300, false, 0x808080);
var bd2:BitmapData=new BitmapData(500, 300, false, 0x808080);

var bmp:Bitmap=new Bitmap(bd);
addChild(bmp);

var isProcessing:Boolean=true;

bd.perlinNoise(150, 150, 3, 50, true, true, 7, true);

stage.addEventListener(MouseEvent.CLICK, toggleProcessing);
function addLayer(event:Event):void {
	var seed:uint=Math.random()*1000;
	var sizex:uint=Math.random()*250+2;
	var sizey:uint=Math.random()*250+2;
	bd2.perlinNoise(sizex, sizey, 3, seed, false, true, 7, true);
	bd.draw(bd2, null, null, BlendMode.DIFFERENCE);
}
function toggleProcessing(event:MouseEvent):void {
	isProcessing ? stage.removeEventListener(Event.ENTER_FRAME, addLayer) : stage.addEventListener(Event.ENTER_FRAME, addLayer);
	isProcessing=!isProcessing;
}

You don't really have to randomize octaves too... I found that three is the perfect compromising number between speed and complexity.

Eventually you could even animate this (even if for very small bitmaps only since you need at least 30 interactions to have some good result. You just need to store random seeds into a array and regenerate the image at every frame using the same seeds but with different octaves offsets.

However for projects where you need a random map generated only once, you shouldn't have problems having a "once only" initial delay of half second.

As instance look at this kind of generated noise applied to my latest voxel experiment:

Test demo #3 (Voxels demo)

Much more interesting mountains than this... don't you think?

As usual drop me some comments, I am courious to know what you think about this.
Bye

6 Comments

6 Comments

  1. vitaLee  •  Nov 3, 2008 @11:03 am

    Wow. this is great.
    You’ve got a star in my google reader for this post. i always find your posts so interesting and inspiring. Great work !!!

  2. Alan Shaw  •  Nov 12, 2008 @6:03 pm

    Excellent!

  3. zu  •  Nov 24, 2008 @4:41 am

    That’s hot!! This is very useful and inspiring, thanks!

  4. Sam  •  Jan 27, 2009 @10:26 pm

    This is brilliant simple but yet very complex!!

  5. Stephen  •  Feb 5, 2010 @5:48 pm

    Excellent, i look forward to stealing some of your code in the future :) , these are great experiments!!!

  6. DakaSha  •  Jan 16, 2012 @5:11 pm

    Hey you inspired me to waste some time (In a good way :P )
    http://quantumsprings.net/perlin-noise-parameter-visualizer

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>