PDA

View Full Version : Perlin Noise and Displacement -- a better understanding.



cupofnestor
January 21st, 2010, 01:19 PM
I've often found uses for displacement via perlin noise generated via BitmapData objects. Usually, i've ended up using hack-y cut-and-paste code, and I want to get a better understanding. I've made a class to handle generating and animating the perlin fumction. Then, using the document class, attempted to displace a MovieClip with it. I've found that I can only use a "local" bitmapData object to serve as the first argument to the displacementMapfilter. And, the filter only "works" for the first few frames, before the appearance of displacement ceases. =-|



//warble.as (document class, needs a mc called Pic)
package
{
import flash.display.MovieClip;
import flash.display.BitmapData;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;
import flash.events.*
public class warble extends MovieClip
{
var displaceBitmap:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
var noisey:perlin=new perlin();
var filter:DisplacementMapFilter;
var img:Pic = new Pic();
var off:Point = new Point(0,0);

public function warble(){
addChild(noisey);
filter= new DisplacementMapFilter(displaceBitmap, off, 1,1,122,-111, "clamp");
addChild(img);
addEventListener(Event.ENTER_FRAME,animate);
}

private function animate(e:Event):void
{
displaceBitmap.draw(noisey);
img.filters=[filter];
}
}
}




//perlin.as
package
{
import flash.display.*;
import flash.geom.Point;
import flash.events.Event;

public class perlin extends MovieClip
{
public var bitmap:BitmapData;
public var image:Bitmap;
private var angle:Number=0;
private var _offsetX:Number=0;
private var _offsetY:Number=0;

public function perlin()
{
this.addEventListener(Event.ADDED_TO_STAGE,init);
}

private function init(e:Event):void
{
this.bitmap=new BitmapData(stage.stageWidth,stage.stageHeight,true ,0xFFFFFFFF);
image = new Bitmap(this.bitmap);
this.addChild(image);
this.addEventListener(Event.ENTER_FRAME,update);
}

private function update(event:Event):void
{
var point:Point=new Point(this._offsetX,0);
var point2:Point=new Point(this._offsetY,this._offsetX);
this.bitmap.perlinNoise(150,75,3,1000,false,true,B itmapDataChannel.ALPHA,false,[point,point2]);
this._offsetX+=1.7856309;
this._offsetX+=1.7232900;
}
}
}

Freshmaker
January 21st, 2010, 01:47 PM
I haven't compiled the code, but I think the problem is that your map is moving off of the movie clip. You'll need to reset or reverse (etc) its position when it begins to move too far away, or generate an additional or bigger displacement map.

To see what's happening, you might render the map to the screen on top of the displaced graphic and see how that compares to the displaced version.

cupofnestor
January 21st, 2010, 02:10 PM
The BitmapData width/height is set to stage.stageWidth/Height.

theCodeBot
January 21st, 2010, 10:39 PM
I like Freshmaker's idea. If you'd like a better idea of how the noise filter is applied, then make a Bitmap from the BitmapData that is the filter, and display that on the stage, so you can see what it is. Then place the MovieClip to be affected on top, and then have the ACTUAL filter BitmapData applied there... If you can move the Bitmap representation and the actual filter at the same time, it should make a pretty good visual representation of exactly what it's doing to your image.

cupofnestor
January 22nd, 2010, 11:01 AM
I like Freshmaker's idea. If you'd like a better idea of how the noise filter is applied, then make a Bitmap from the BitmapData that is the filter, and display that on the stage, so you can see what it is. Then place the MovieClip to be affected on top, and then have the ACTUAL filter BitmapData applied there... If you can move the Bitmap representation and the actual filter at the same time, it should make a pretty good visual representation of exactly what it's doing to your image.

If you'd read the code, you'd both know that is exactly what I'm doing. The problem was that I was generating grayscale noise, and it works better if there are two color channels: 1 for x-displacement and one for y.