// ------------------------------------------------- // // 線状にサインカーブで波打つフィルタ // // // ------------------------------------------------- package { import flash.events.*; import flash.display.*; import flash.net.*; import flash.text.*; import flash.utils.*; import flash.system.*; import flash.geom.*; import flash.filters.*; import flash.ui.*; public class Main extends Sprite { public function Main() { // ------------------------------------------------- // コンストラクタ // ------------------------------------------------- // フレームレート stage.frameRate = 60; // 100%表示 stage.scaleMode = StageScaleMode.NO_SCALE; // 左上 stage.align = StageAlign.TOP_LEFT; stage.align = "TL"; // スプライトを配置 var board : Sprite = new Sprite(); addChild(board); // リソース読み込み開始 load(); // ------------------------------------------------- // 読み込み // ------------------------------------------------- function load():void{ // 画像のURL var graphic_url:String = "http://actionscript.web.officelive.com/wonderfl/bg001.jpg"; // ローダー var loader_obj : Loader = new Loader(); // 読み込み開始 var url : URLRequest = new URLRequest(graphic_url); loader_obj.load(url); // 読み込み終了 var info : LoaderInfo = loader_obj.contentLoaderInfo; info.addEventListener (Event.INIT,LoaderInfoInitFunc); function LoaderInfoInitFunc (event : Event):void { // 読み込んだ画像を表示 board.addChild(loader_obj); // 初期化へ init(); } } // ------------------------------------------------- // 初期化 // ------------------------------------------------- function init():void{ // ステージサイズ var w:uint; var h:uint; // リサイズ時にフィット stage.addEventListener(Event.RESIZE,ResizeFunc); function ResizeFunc(e:Event):void{ w = stage.stageWidth; h = stage.stageHeight; board.width = w; board.height = h; } ResizeFunc(null); // シェーダバイトコード var binary : ByteArray = CustomFilterGetByteArray(); // シェーダ作成 var shader:Shader = new Shader(); shader.byteCode = binary; var filter:ShaderFilter = new ShaderFilter(shader); // パラメータアクセス用 var data : ShaderData = shader.data; var param : ShaderParameter; // パラメータ var phase:Number = 0; // 位相 var amplitude:Number = 30; // 振幅 var cycle:Number = 300; // 周期 addEventListener(Event.ENTER_FRAME,function(e:Event):void{ // 位相を変化 phase += 0.01; if(phase > 1) phase -= 1; // 角度 var rot : Number = Math.atan2(h/2 - mouseY,w/2 - mouseX) * 180 / Math.PI; param = data.rotate; param.value = [rot]; // 位相 param = data.phase; param.value = [phase]; // 振幅 param = data.amplitude; param.value = [amplitude]; // 周期 param = data.cycle; param.value = [cycle]; // 適応 board.filters = [filter]; }); // テキスト表示 var tf : TextField = new TextField(); tf.x = 5; tf.y = 5; tf.width = 200; tf.height = 40; tf.border = true; tf.background = true; addChild(tf); addEventListener(Event.ENTER_FRAME,function(e:Event):void{ var str:String = ""; str += "振幅:" + amplitude + " (上下キーで変更)\n"; str += "周期:" + cycle + " (左右キーで変更)\n"; tf.text = str; }); // キー操作 stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown); function KeyDown(event:KeyboardEvent):void{ if(event.keyCode == Keyboard.UP) amplitude -= 1; if(event.keyCode == Keyboard.DOWN) amplitude += 1; if(event.keyCode == Keyboard.LEFT) cycle -= 10; if(event.keyCode == Keyboard.RIGHT) cycle += 10; if(amplitude < 0) amplitude = 0; if(cycle < 0) cycle = 0; }; } // ------------------------------------------------- // シェーダバイトコード // ------------------------------------------------- function CustomFilterGetByteArray():ByteArray{ var a:ByteArray = new ByteArray(); var f:Function; f = a.writeUnsignedInt; f(0xa5010000); f(0x00a41300); f(0x43757276); f(0x65576176); f(0x654c696e); f(0x6546696c); f(0x746572a0); f(0x0c6e616d); f(0x65737061); f(0x63650063); f(0x75727665); f(0x20776176); f(0x65206c69); f(0x6e6500a0); f(0x0c76656e); f(0x646f7200); f(0x48616b75); f(0x68696e00); f(0xa0087665); f(0x7273696f); f(0x6e000100); f(0xa00c6465); f(0x73637269); f(0x7074696f); f(0x6e0090fc); f(0x8ff382c9); f(0x83548343); f(0x8393834a); f(0x815b8375); f(0x82c59467); f(0x91c582c2); f(0x83748342); f(0x838b835e); f(0x00a10102); f(0x00000c5f); f(0x4f757443); f(0x6f6f7264); f(0x00a30004); f(0x73726300); f(0xa1020401); f(0x000f6473); f(0x7400a101); f(0x01000002); f(0x6379636c); f(0x6500a201); f(0x6d696e56); f(0x616c7565); f(0x003f8000); f(0x00a20164); f(0x65666175); f(0x6c745661); f(0x6c756500); f(0x42c80000); f(0xa20c6465); f(0x73637269); f(0x7074696f); f(0x6e009467); f(0x82aa88ea); f(0x8efc82b7); f(0x82e992b7); f(0x82b300a1); f(0x01010000); f(0x01706861); f(0x736500a2); f(0x016d696e); f(0x56616c75); f(0x65000000); f(0x0000a201); f(0x6d617856); f(0x616c7565); f(0x003f8000); f(0x00a20164); f(0x65666175); f(0x6c745661); f(0x6c756500); f(0x00000000); f(0xa20c6465); f(0x73637269); f(0x7074696f); f(0x6e009467); f(0x82cc88ca); f(0x918a00a1); f(0x01010200); f(0x08616d70); f(0x6c697475); f(0x646500a2); f(0x016d696e); f(0x56616c75); f(0x65000000); f(0x0000a201); f(0x64656661); f(0x756c7456); f(0x616c7565); f(0x00412000); f(0x00a20c64); f(0x65736372); f(0x69707469); f(0x6f6e0094); f(0x6782cc97); f(0x6882ea95); f(0x9d00a101); f(0x01020004); f(0x726f7461); f(0x746500a2); f(0x016d696e); f(0x56616c75); f(0x65000000); f(0x0000a201); f(0x6d617856); f(0x616c7565); f(0x0043b400); f(0x00a20164); f(0x65666175); f(0x6c745661); f(0x6c756500); f(0x00000000); f(0xa20c6465); f(0x73637269); f(0x7074696f); f(0x6e009467); f(0x82cc8a70); f(0x93780032); f(0x0200203c); f(0x8efa3503); f(0x02002002); f(0x0040001d); f(0x02001002); f(0x0080000d); f(0x02002002); f(0x00c0001d); f(0x03008002); f(0x0080000c); f(0x02002002); f(0x00c0001d); f(0x03004002); f(0x0080001d); f(0x03003103); f(0x00100032); f(0x02002042); f(0xb400001d); f(0x03008002); f(0x00400001); f(0x03008002); f(0x00800032); f(0x0200203c); f(0x8efa3503); f(0x02002003); f(0x0000001d); f(0x02001002); f(0x0080001d); f(0x0300c100); f(0x0010001d); f(0x02002003); f(0x00800003); f(0x02002003); f(0x0000001d); f(0x04008003); f(0x00c00003); f(0x04008003); f(0x0040001d); f(0x04004002); f(0x00800001); f(0x04004004); f(0x00000032); f(0x02002000); f(0x00000002); f(0x02002004); f(0x0040001d); f(0x04008002); f(0x0080001d); f(0x04006103); f(0x00b00003); f(0x04006104); f(0x0000001d); f(0x03003104); f(0x0060001d); f(0x02002003); f(0x00800003); f(0x02002003); f(0x0080001d); f(0x04004003); f(0x00c00003); f(0x04004003); f(0x00c0001d); f(0x04002002); f(0x00800001); f(0x04002004); f(0x00400016); f(0x02002004); f(0x0080001d); f(0x04004002); f(0x00800004); f(0x02002000); f(0x00800003); f(0x02002004); f(0x0040001d); f(0x04002002); f(0x0080001a); f(0x02002004); f(0x0080001d); f(0x04001004); f(0x00800002); f(0x04001002); f(0x0080001d); f(0x04002004); f(0x00c0001d); f(0x02002004); f(0x00800001); f(0x02002000); f(0x00c00032); f(0x04001043); f(0xb400001d); f(0x05008002); f(0x00800003); f(0x05008004); f(0x00c00032); f(0x0200203c); f(0x8efa3503); f(0x02002005); f(0x0000000c); f(0x04001002); f(0x0080001d); f(0x02002004); f(0x00c00003); f(0x02002002); f(0x0000001d); f(0x04004002); f(0x0080000d); f(0x02002002); f(0x00c0001d); f(0x04001002); f(0x00800003); f(0x04001004); f(0x00400001); f(0x03008004); f(0x00c0000c); f(0x02002002); f(0x00c0001d); f(0x04001002); f(0x00800003); f(0x04001004); f(0x00400001); f(0x03004004); f(0x00c00031); f(0x0500f103); f(0x0010001d); f(0x0100f305); f = a.writeShort; f(0x001b); f = a.writeByte; f(0x00); return a; } } } } // ↓ pbk ファイルのコード /* ----------------------------------------------------------------------------- パラメータ cycle 波が一周する長さ phase 波の位相 ( 0 ~ 1 までゆっくり変化させる) amplitude 波の揺れ幅 rotate 波の角度(0~360) ----------------------------------------------------------------------------- */ /* <languageVersion : 1.0;> kernel CurveWaveLineFilter< namespace : "curve wave line"; vendor : "Hakuhin"; version : 1; description : "線状にサインカーブで波打つフィルタ"; >{ input image4 src; // 入力イメージ output pixel4 dst; // 出力ピクセル // ------------------------------------- // パラメータ // ------------------------------------- parameter float cycle< minValue:float(1.0); defaultValue:float(100.0); description : "波が一周する長さ"; >; parameter float phase< minValue:float(0.0); maxValue:float(1.0); defaultValue:float(0); description : "波の位相"; >; parameter float amplitude< minValue:float(0.0); defaultValue:float(10.0); description : "波の揺れ幅"; >; parameter float rotate< minValue:float(0.0); maxValue:float(360.0); defaultValue:float(0); description : "波の角度"; >; // ------------------------------------- // ピクセルごとに実行される関数 // ------------------------------------- void evaluatePixel(){ // 角度をラジアンに変更 float rad = radians(rotate); // ラジアンをベクトルに変換 float2 v = float2(cos(rad),sin(rad)); // 運動させたいラジアン方向に変更 rad = radians(rotate + 90.0); // ピクセルの位置を取得 float2 pos = outCoord(); // 角度に垂直で原点を通る線と現在の位置との距離を取得 float t = -(v.x * pos.x + v.y * pos.y); v = v * t; float distance = sqrt((v.x * v.x) + (v.y * v.y)); // 周期に丸める float d = distance / cycle; d = d - floor(d); // オフセットを取得して座標に加算 distance = sin(radians((d + phase) * 360.0)) * amplitude; pos.x += cos(rad) * distance; pos.y += sin(rad) * distance; // ソースイメージからピクセルカラーを取得して出力 dst = sampleLinear(src,pos); } } */ // ------------------------------------------------- // 外部画像をサムネイルとしてキャプチャ // ------------------------------------------------- import flash.net.*; import flash.events.*; import flash.display.*; import flash.geom.*; function ThumbnailCapture(url:String,time:uint,stage:Stage):void{ // キャプチャタイミング Wonderfl.capture_delay( time ); // スプライト作成 var sprite : Sprite = new Sprite(); // ステージ最前面に配置 stage.addChildAt(sprite,stage.numChildren); // ローダー var loader_obj : Loader = new Loader(); loader_obj.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{ // メモリからインスタンス化 var loader_memory : Loader = new Loader(); loader_memory.contentLoaderInfo.addEventListener (Event.INIT,function(e:Event):void{ // キャプチャ var bmp : BitmapData = new BitmapData(loader_memory.width,loader_memory.height,true,0); sprite.addChild(loader_memory); bmp.draw(sprite); sprite.removeChild(loader_memory); loader_memory.unload(); loader_obj.unload(); loader_memory = null; loader_obj = null; // 画像を配置 var bmp_obj : Bitmap = new Bitmap(bmp); bmp_obj .width = stage.stageWidth; bmp_obj .height = stage.stageHeight; stage.addChild(bmp_obj ); }); // 読み込み開始 loader_memory.loadBytes(loader_obj.contentLoaderInfo.bytes); }); // 読み込み開始 loader_obj.load(new URLRequest(url)); } Pixel Bender (線状にサインカーブで波打つフィルタ)