LOGv:20171214

パーリンノイズで遊ぶ2

パーリンノイズを使って炎の演出をしてみた。
参考:http://wonderfl.net/c/rolo/
結果

openFL2.2.4
出力対象flash
package;

import openfl.Assets;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
import flash.geom.Point;

class Main extends Sprite{
private var W : Int = 300;
private var H : Int = 300;
private var ZERO_POINT : Point = new Point(0,0);
private var fireColor : BitmapData; // 炎の色情報
private var drawData : BitmapData; // 描く内容
private var coolingData : BitmapData; // 火消し用
private var offset : Array<Point>; // 炎の揺らぎ
private var palette : Array<Int>; // 色情報
private var zeroArray : Array<Int>; // 使わない色配列を0で埋める
private var ball : Sprite; // 火の玉
private var canvas : Sprite; // 火の玉設置用
private var spred : ConvolutionFilter; // ぼかし用フィルター
private var color : ColorMatrixFilter; // 火消し用フィルター
private var viewData : BitmapData; // 描画用
private var view : Bitmap;
// =========================================================================
// 火の玉の移動
// =========================================================================
private function mouseMoveHandler(e:MouseEvent):Void{
ball.x = stage.mouseX;
ball.y = stage.mouseY;
}
// =========================================================================
// 描画
// =========================================================================
private function enterFrameHandler(e:Event):Void {
drawData.draw(canvas);
drawData.applyFilter(drawData,drawData.rect,ZERO_POINT,spred);
coolingData.perlinNoise(25,25,2,5,false,false,0,true,offset);
offset[0].x += 2.0;
offset[1].y += 0.2;
coolingData.applyFilter(coolingData, coolingData.rect, ZERO_POINT, color);
drawData.draw(coolingData, null, null, BlendMode.SUBTRACT);
drawData.scroll(0,-3);
viewData.paletteMap(drawData, drawData.rect, ZERO_POINT, palette, zeroArray, zeroArray, zeroArray);
}
// =========================================================================
public function new(){
super();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality = StageQuality.LOW;
palette = [];
zeroArray = [];
offset = [new Point(), new Point()];
fireColor = Assets.getBitmapData('img/fire.jpg');
canvas = new Sprite();
ball = new Sprite();
drawData = new BitmapData(W,H,false,0x0);
coolingData = new BitmapData(W,H,false,0x0);
viewData = new BitmapData(W,H,false,0x0);
spred = new ConvolutionFilter(3,3,[
0, 1, 0,
1, 1, 1,
0, 1, 0
],5);
color = new ColorMatrixFilter([
0.3, 0, 0, 0, 0,
0, 0.3, 0, 0, 0,
0, 0, 0.3, 0, 0,
0, 0, 0, 1, 0
]);
canvas.graphics.beginFill(0x0,0);
canvas.graphics.drawRect(0,0,W,H);
canvas.graphics.endFill();
ball.graphics.beginFill(0xFFFFFF,1);
ball.graphics.drawEllipse(-7,-20,14,20);
canvas.addChild(ball);
for(i in 0...256){
palette.push(fireColor.getPixel(i,0));
zeroArray.push(0);
}
addChild(new Bitmap(Assets.getBitmapData('img/bg.jpg')));
view = new Bitmap(viewData);
view.blendMode = BlendMode.LIGHTEN;
addChild(view);
// ---------------------------------------------------------------------
addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveHandler,false);
addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}


}

BitmapData.getPixel

ピクセルの色を取得する。(24bitカラー)
アルファ値もとりたいときは、BitmapData.getPixel32を利用

返り値UInt
引数初期値説明
x Intx座標
y Inty座標

ConvolutionFilterクラス

隣接するピクセル(行列で表現)を考慮し、ピクセルの色を変更するフィルター
ぼかし、シャープ、エンボス効果、エッジ検出etc.が出来る
参照→ConvolutionFilter – AS3 Flex

引数初期値説明
matrixX0Floatmatrixのx次元
※ 列数
matrixY0Float matrixのy次元
※ 行数
matrixnullArray<Dynamic>マトリックス変換に使用する値の配列(隣接するピクセル)
※ matrixX * matrixY に等しい
divisor1Floatマトリックス変換中に使用する除数です。
除数がすべてのマトリックス値の合計と等しい場合は、結果全体のカラー強度が均等化されます。値 0 は無視され、代わりにデフォルト値が使用されます。
bias0Floatマトリックス変換の結果に加算するバイアスです。
preserveAlphatrueBooleanfalse である場合は、アルファ値が保持されず、アルファチャンネルを含め、すべてのチャンネルに畳み込みを適用します。true である場合は、畳み込みをカラーチャンネルだけに適用します。
clamptrueBooleantrue の場合、ソースイメージの外にあるピクセルに対して、入力イメージの所定のエッジのカラー値を複製するという方法で、必要に応じて境界に沿って入力イメージを拡張します。false の場合は、別の色を使用します。その色は color プロパティと alpha プロパティで指定します。
color0UIntソースイメージの外にあるピクセルを置換する 16 進数のカラー値です。
alpha0Float代替カラーのアルファ

ColorMatrixFilterクラス

RGBA値の強さの変更や値の置き換え等が出来る。
彩度変更、色相回転、輝度アルファ変換etc.が出来る。
ColorMatrixFilter – AS3

引数初期値説明
matrixnullArray<Float>4×5のマトリクス構造の配列
引数matrixR値の強さG値の強さB値の強さA値の強さ計算後に加算する値
R値計算のエレメントa0a1a2a3a4
G値計算のエレメントa5a6a7a8a9
B値計算のエレメントa10a11a12a13a14
A値計算のエレメントa15a16a17a18a19
行列の計算式
R new | a0 | a1 | a2 | a3 | | R | | a4 |
G new = | a5 | a6 | a7 | a8 | * | G | + | a9 |
B new   | a10 | a11 | a12 | a13 | | B | | a14 |
A new | a15 | a16 | a17 | a18 | | A | | a19 |

↓↓↓↓

R new | a0*R + a1*R + a2*R + a3*R | | a4 |
G new = | a5*G + a6*G + a7*G + a8*G | + | a9 |
B new | a10*B + a11*B + a12*B + a13*B | | a14 |
A new | a15*A + a16*A + a17*A + a18*A | | a19 |

↓↓↓↓

R new | (a0*R + a1*R + a2*R + a3*R) + a4 |
G new = | (a5*G + a6*G + a7*G + a8*G) + a9 |
B new | (a10*B + a11*B + a12*B + a13*B) + a14 |
A new | (a15*A + a16*A + a17*A + a18*A) + a19 |

設定例

// 赤のみにする
// 上のn値の強さは引き継ぎ値、R値の強さが1ならフィルター前の値をそのまま継承。下の例だと赤成分のみ残る
var myFilter = new ColorMatrixFilter([
1, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 0
]);

// 赤で塗りつぶし
// G,B,A値をR値に入れる
var myFilter = new ColorMatrixFilter([
1, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 1, 0
]);

// 1.5倍明るくする
var myFilter = new ColorMatrixFilter([
1.5, 0, 0, 0, 0,
0, 1.5, 0, 0, 0,
0, 0, 1.5, 0, 0,
0, 0, 0, 1, 0
]);

---------------------------------------
実装例
---------------------------------------
package;

import openfl.Assets;
import flash.display.Sprite;
import flash.filters.ConvolutionFilter;
import flash.filters.ColorMatrixFilter;
import flash.display.Bitmap;
import flash.display.BitmapData;

class Main extends Sprite{
public function new(){
var a : UInt
var bg : Bitmap = new Bitmap(Assets.getBitmapData('img/bg.jpg'));
var param : Array<Float> = [
1.5, 0, 0, 0, 0,
0, 1.5, 0, 0, 0,
0, 0, 1.5, 0, 0,
0, 0, 0, 1, 0
];
var myFilter : ColorMatrixFilter = new ColorMatrixFilter(param);
this.addChild(bg);
bg.filters = [
myFilter
];
super();
}
}

BitmapData.paletteMap

RGBA配列(各チャンネルごとに 1 つの配列)を使用して、第1引数のカラーチャンネル値をマッピングし直す

引数初期値説明
sourceBitmapData BitmapData入力
sourceRect Rectangle 
destPoint Point 
readArraynullArray<UInt> 
greenArraynullArray<UInt> 
blueArraynullArray<UInt> 
aplhaArraynullArray<UInt> 

参考 / 引用

open close