2012年6月13日 星期三

water effect using perlinNoise and DisplacementMapFilter

水波/流體效果

說明如下,
1. 利用 BitmapData perlinNoise 生出雜點紋理圖像
2. 產生可 loop 的參考圖像
3. 捲動參考圖像,參考紅綠兩個 channel

perlinNoise 用法
perlinNoise(baseX:Number, baseY:Number, numOctaves:uint, randomSeed:int,
stitch:Boolean,
fractalNoise:Boolean,
channelOptions:uint = 7,
grayScale:Boolean = false,
offsets:Array = null)

baseX:Frequency to use in the x direction.
baseY:Frequency to use in the y direction.
numOctaves:數值愈高產生的圖像愈細緻
randomSeed:random seed
stitch:true 平滑影像邊緣,以建立無接縫的拼貼紋理,適用於水波。
fractalNoise:true 平滑化該效果的邊緣,適用於雲霧,false 明顯不連續的漸層,適用於火焰和海浪。
channelOptions:套用的顏色,這裡是用紅綠。
grayScale:灰階
offsets:x,y 偏移陣列

完整 code 如下:
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.filters.DisplacementMapFilter;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* 水波效果
*/
[SWF(width="1024",height="700",frameRate="30",backgroundColor="0xFFFFFF")]
public class Main extends Sprite
{
[Embed(source="../assets/bg.jpg")] private var ImageClass:Class;
private const IMAGE_W:int = 1024;
private const IMAGE_H:int = 700;
private var dmf:DisplacementMapFilter;
private var image:Bitmap;
private var map:BitmapData;
private var dmfmap:BitmapData;
private var uScroll:int = 0, uRect:Rectangle;
private var vScroll:int = IMAGE_W, vRect:Rectangle;
public function Main():void
{
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var temp:BitmapData = new BitmapData(IMAGE_W, IMAGE_H, false, 0x0);
temp.perlinNoise(IMAGE_W, IMAGE_H, 8, Math.random() * int.MAX_VALUE, true, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN);
// loop image
map = new BitmapData(IMAGE_W * 2, IMAGE_H, false, 0x0);
map.copyPixels(temp, temp.rect, new Point);
map.copyPixels(temp, temp.rect, new Point(IMAGE_W, 0));
temp.dispose();
dmfmap = new BitmapData(IMAGE_W, IMAGE_H, false, 0x0);
dmf = new DisplacementMapFilter(dmfmap,
new Point,
BitmapDataChannel.RED,
BitmapDataChannel.GREEN,
100, 100);
uRect = new Rectangle(0, 0, IMAGE_W, IMAGE_H);
vRect = new Rectangle(0, 0, IMAGE_W, IMAGE_H);
addEventListener(Event.ENTER_FRAME, drawEffect);
image = new ImageClass();
addChild(image);
}
private function drawEffect(e:Event):void
{
uScroll += 3;
vScroll -= 3;
if (uScroll > IMAGE_W) uScroll = 0;
if (vScroll < 0) vScroll = IMAGE_W;
// 捲動參考圖像
uRect.x = uScroll;
vRect.x = vScroll;
dmfmap.copyChannel(map, uRect, new Point, BitmapDataChannel.RED, BitmapDataChannel.RED);
dmfmap.copyChannel(map, vRect, new Point, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN);
image.filters = [dmf];
}
}
}
view raw waterEffect.as hosted with ❤ by GitHub

沒有留言:

張貼留言