Animeret Perlin noise
Beklager, du har ikke den krævede version af Flash Player. Du kan hente den fra http://www.adobe.com/go/getflash/
Intro
Denne guide er beregnet som en introduktion til og nem opsætning af et animeret Perlin noise. Den er baseret på arbejdet af Seb Lee-Delisle(http://www.sebleedelisle.com/2007/11/3d-perlin-noise-in-flash/), Ron Valstar(http://www.sjeiti.com/?p=305) og selvfølgelig Ken Perlin(http://mrl.nyu.edu/~perlin/doc/oscar.html).
Perlin noise er et specialiseret slags noise som har en smoothing/gradient:

Denne type noise kan bruges til mange ting, både direkte visuelt, men også til at styre visuelle elementer eller pathing, flocking og animation af objekter. Da Perlin noise består af gradienter egner det sig godt til at generere organiske og flydende animationer.
Perlin noise som 3D terræn:
http://larry.onlinekarma.net/tutorials/Sandy3/Terrain/bin/WaterTerrain.s...
Perlin noise til at lave flocking:
http://www.kelvinluck.com/2007/11/flash-on-the-beach-and-some-perlin-noi...
Princippet
Her i guiden vil jeg fokusere på at lave et animeret Perlin noise ligesom det Seb har lavet(http://www.sebleedelisle.com/2007/11/3d-perlin-noise-in-flash/).
Princippet bag et animeret Perlin noise er at generere et 3D Perlin noise og så animere ved at tage "slices" på z-aksen, dette giver en flydende animation, hvorimod hvis man bare gentegnede et 2D Perlin noise med et nyt seed(tilfældighed) ville det give et meget hakkende resultat.
Flash understøtter som standard kun 2D Perlin noise med BitmapData.perlinNoise(), men heldigvis har Ron Valstar konverteret Ken Perlin's originale 3D Perlin Noise til AS3 hvorefter Mario Klingemann har lavet nogle optimeringer af klassen. Den kan downloades her: http://www.quasimondo.com/archives/000672.php
Her er et eksempel lavet af Ron Valstar hvor klassen er brugt, den viser også de forskellige parametre man kan stille på:
Beklager, du har ikke den krævede version af Flash Player. Du kan hente den fra http://www.adobe.com/go/getflash/
Inden jeg viser hele koden der skal til for at få et animeret Perlin Noise til at køre så lad os lige kigge på et par kodestumper.
Perlin settings
Først de settings vi laver på OptimizedPerlin klassen(den vi downloadede), det er de samme parametre som vi havde i ovenstående eksempel.
// settings for the perlin noise renderer // size of areas, integers, higher = smaller areas = more detailed OptimizedPerlin.octaves = 3; // smoothing, values: 0-1, lower = more smooth OptimizedPerlin.falloff = 0.5; // generate perlin seed(randomness) OptimizedPerlin.seed = Math.round(Math.random() * 123);
Octaves er mængden/størrelsen af "områder" og dermed også detaljegraden, højere betyder flere "områder" mere detaljeret. Falloff er mængden af smoothing(gradient graden), lavere betyder mere smoothing. Seed er hvilken "opsætning" man får, så man sætter den til et random tal hver gang til at få et forskelligt resultet.
// create bitmapdata that we will draw perlin map onto, keep size small for fast render _perlinData = new BitmapData(50,25,false,0x000000); // create bitmap for perlin bitmapdata, smoothing is important cause it will be scaled var perlinBitmap:Bitmap = new Bitmap(_perlinData,"auto",true);
Det bitmapData vi genererer vores Perlin noise på skal være meget lille(her 50x25px) for at vi kan generere vores noise hurtigt nok til at animere det, men heldigvis kan vi bare skalere vores bitmap op med smoothing på og stadig få et godt resultet.
Draw Perlin
Her er metoden som genererer og tegner vores Perlin noise:
// DRAW PERLIN private function drawPerlin():void { // lock the bitmapdata (block updates) _perlinData.lock(); // run through each pixel in the bitmapdata for (var i:Number = 0; i < _perlinData.width; ++i) { for (var j:Number = 0; j < _perlinData.height; ++j) { // get value from perlin noise (0-1) var noiseValue:Number = OptimizedPerlin.noise( i/_perlinData.width, j/_perlinData.height, _zValue ); // convert value to color amount (0-255) var noiseColorValue:int = int( (.5+1.*(noiseValue-.5))*255 ); // create blue color between full blue and full white var color:uint = noiseColorValue << 16 | noiseColorValue << 8 | 255; // set color on bitmapdata pixel _perlinData.setPixel(i, j, color); } } //unlock the bitmapdata _perlinData.unlock(); }
Vi starter og slutter med at låse vores bitmapdata så der ikke bliver sendt updates til vores bitmap for hver pixel vi løber igennem. Efter den er låst så løber vi igennem hver pixel vi har i vores bitmapdata og får Perlin noise værdien med OptimizedPerlin.noise(), som tager imod x, y og z parametre som alle skal være meget lave tal. Herefter konverterer vi værdien fra 0-1 til 0-255 så vi kan bruge det til at lave en farve, så laver vi en blå farve mellem helt blå og helt hvid, og til sidst tegner vi farven på den pixel i vores bitmapdata som vi er kommet til.
Enter Frame
Til sidst har vi den funktion der sørger for at animere vores Perlin noise, den bliver kaldt hver frame.
// ENTER FRAME HANDLER private function enterFrameHandler(event:Event):void { // draw perlin map drawPerlin(); // increment z value used for perlin map _zValue += 0.04; }
Her tegner vi vores Perlin noise og hæver z værdien.
Dette er stort set alt der skal til for at få lavet et animeret Perlin noise, den fulde kode som jeg bare har sat som document class i Flash CS4 kan ses her:
Kildekode
package { // IMPORTS import flash.display.Sprite; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.display.BitmapData; import flash.display.Bitmap; import flash.events.Event; import nl.ronvalstar.math.OptimizedPerlin; // CLASS public class PerlinAnim extends Sprite { //PRIVATE VARS private var _perlinData:BitmapData; private var _perlinHolder:Sprite; private var _zValue:Number = 1; // CONSTRUCTOR public function PerlinAnim() { // set stage scale and align stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; // initialize init(); } // INIT private function init():void { // create the perlin bitmaps etc. setupPerlin(); // listen for stage resize and enter frame stage.addEventListener(Event.RESIZE, stageResizeHandler, false, 0, true); addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true); } // SETUP PERLIN private function setupPerlin():void { // settings for the perlin noise renderer // size of areas, integers, higher = smaller areas = more detailed OptimizedPerlin.octaves = 3; // smoothing, values: 0-1, lower = more smooth OptimizedPerlin.falloff = 0.5; // generate perlin seed(randomness) OptimizedPerlin.seed = Math.round(Math.random() * 123); // create bitmapdata that we will draw perlin map onto, keep size small for fast render _perlinData = new BitmapData(50,25,false,0x000000); // create bitmap for perlin bitmapdata, smoothing is important cause it will be scaled var perlinBitmap:Bitmap = new Bitmap(_perlinData,"auto",true); // setup holder and add to stage _perlinHolder = new Sprite(); _perlinHolder.addChild(perlinBitmap); addChild(_perlinHolder); // scale perlin holder to stage size stageResizeHandler(null); } // DRAW PERLIN private function drawPerlin():void { // lock the bitmapdata (block updates) _perlinData.lock(); // run through each pixel in the bitmapdata for (var i:Number = 0; i < _perlinData.width; ++i) { for (var j:Number = 0; j < _perlinData.height; ++j) { // get value from perlin noise (0-1) var noiseValue:Number = OptimizedPerlin.noise( i/_perlinData.width, j/_perlinData.height, _zValue ); // convert value to color amount (0-255) var noiseColorValue:int = int( (.5+1.*(noiseValue-.5))*255 ); // create blue color between full blue and full white var color:uint = noiseColorValue << 16 | noiseColorValue << 8 | 255; // set color on bitmapdata pixel _perlinData.setPixel(i, j, color); } } //unlock the bitmapdata _perlinData.unlock(); } // ENTER FRAME HANDLER private function enterFrameHandler(event:Event):void { // draw perlin map drawPerlin(); // increment z value used for perlin map _zValue += 0.04; } // STAGE RESIZE HANDLER private function stageResizeHandler(event:Event):void { // scale perlin holder to stage _perlinHolder.scaleX = stage.stageWidth/_perlinData.width; _perlinHolder.scaleY = stage.stageHeight/_perlinData.height; } } }
Download
Kilde filerne kan downloades her:
http://flashforum.dk/files/artmos/AnimatedPerlinNoise.zip
- log ind eller opret konto for at skrive kommentarer

