Recipe 8.11. Creating Perlin Noise


Problem

You want to create random organic effects, such as clouds, smoke, or water.

Solution

Use the perlinNoise( ) method of the BitmapData class.

Discussion

Like the noise( ) method, perlinNoise( ) creates random patterns on a bitmap. However, Perlin noise uses an algorithm that produces smooth, organic-looking textures. It was created by Ken Perlin for creating textures in the movie Tron. These textures are perfect for use as explosions, smoke, water, and many other natural-looking effects, and since they are generated by an algorithm, they require much less memory than bitmap-based textures. The usage is as follows:

bitmap.perlinNoise(baseX, baseY, octaves, seed, stitch, fractal,                 channels, grayscale, offsets);

The first six parameters are necessary; the final three are optional. Since there are so many parameters to consider, let's create a simple example and then see what each one does. The following code creates a bitmap, applies Perlin noise to it and then displays it:

bitmap = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0xff000000); bitmap.perlinNoise(100, 100, 1, 1000, false, false, 1, true, null); var image:Bitmap = new Bitmap(bitmap); addChild(image);

Add this code to a new class, and run it to see a simple Perlin noise pattern. See Figure 8-1 for an example of what you should see. Now you can start changing parameters and see what effect the changes have.

First off, baseX and baseY determine the size of the pattern. Here they are set to 100 each. Try changing baseX to 200 and baseY to 50 and see how that stretches out the noise horizontally. Already you can see that it looks a bit like rippling water, as you can see in Figure 8-2.

Figure 8-1. Simple Perlin noise


Figure 8-2. Perlin noise stretched on the x axis


The octaves parameter is an integer that determines how many iterations of noise to create. More octaves makes more detailed noise, and of course take longer to produce.

The seed parameter works exactly like the seed in the noise( ) method. If you specify the same seed each time you run the program, you get the same noise pattern. Setting this to a random number gives you a different pattern each time.

The stitch parameter, when set to true, makes the left and right, and top and bottom sides of the pattern match up. This allows you to make a small bitmap and tile it, such as in a bitmap fill from the drawing API, as shown in the following example:

bitmap = new BitmapData(100, 100, false, 0xff000000); bitmap.perlinNoise(100, 100, 2, 1000, true, false, 1, true); graphics.beginBitmapFill(bitmap); graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); graphics.endFill(  );

Here, the bitmap is 100x100, and the stitch parameter is set to true in the perlinNoise( ) call. The bitmap is used as a bitmap fill and tiles seamlessly.

When set to true, the fractal parameter results in the edges of the gradients being smoothed out more. To see it in action, start with this code:

bitmap = new BitmapData(stage.stageWidth, stage.stageHeight,                       false, 0xff000000); bitmap.perlinNoise(200, 100, 5, 1000, false, false, 1, true, null); var image:Bitmap = new Bitmap(bitmap); addChild(image);

After you see the image that creates, change fractal to TRue:

bitmap.perlinNoise(200, 100, 5, 1000, false, true, 1, true, null);

Notice the difference that made (see Figure 8-3)? This parameter is useful for making things like cloud or fog, as you can see by the example, which is already starting to look like clouds.

Figure 8-3. Perlin noise with fractal set to true


The next two parameters, channel and grayscale, work exactly like they do in the noise( ) method. The channel can be any of the following: 1, 2, 4, or 8, representing the red, green, blue, and alpha channels, respectively. 1 has been used in the examples so far, for brevity, but it is recommended that you use the static properties of the BitmapDataChannel class: RED, GREEN, BLUE, and ALPHA, to avoid typos.

Of course, if you set grayscale to TRue, it doesn't matter which color channel you specify, as the resulting image will be grayscale. However, if you set it to false and specify one or more color channels, you can create colored patterns. The next example creates some red clouds:

bitmap.perlinNoise(200, 100, 5, 1000, false, true,                  BitmapDataChannel.RED, false, null);

The following code produces a multicolor pattern by using all three color channels:

bitmap.perlinNoise(200, 100, 5, 1000, false, true,                  BitmapDataChannel.RED |                 BitmapDataChannel.GREEN |                 BitmapDataChannel.BLUE,                 false, null);

You can also make Perlin noise on the alpha channel, which is useful for creating transparent cloud effects or fog.

The final parameter is offsets. This is an array of Point objects. Each point specifies how much a single octave is offset on the X- and Y-axes. If your Perlin noise has more than one octave, you probably want to make an array of points equal in length to the number of octaves, and include the same point for each element. Otherwise, each octave scrolls differently, or not at all. Of course, you can use this for some interesting parallax effects. The following example shows a two-octave Perlin noise pattern scrolling on the X-axis:

package {     import flash.display.Sprite;     import flash.display.Bitmap;     import flash.display.BitmapData;     import flash.events.Event;     import flash.geom.Point;     public class Clouds extends Sprite {         private var _bitmap:BitmapData;         private var _xoffset:int = 0;         public function Clouds(  ) {             _bitmap = new BitmapData(stage.stageWidth, stage.stageHeight,                                  true, 0xffffffff);             var image:Bitmap = new Bitmap(_bitmap);             addChild(image);             addEventListener(Event.ENTER_FRAME, onEnterFrame);         }         public function onEnterFrame(event:Event):void {             _xoffset++;             var point:Point = new Point(_xoffset, 0);             // use the same point in both elements             // of the offsets array             _bitmap.perlinNoise(200, 100, 2, 1000, false, true,                             1, true, [point, point]);         }     } }

See Also

Recipes 8.5 , 8.6, 8.7 , 8.8, 8.9, and 8.10 for other ways to add graphical content to a bitmap.




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net