屈折の続き
ソレはソレとして,id:keim_at_Si:20070930の続き.
2DメタボールのConvolutionFilterは,基本的に電界マップの微分値を取るために使ってるんだけど,
そもそも,電界マップはグレースケール画像なので,RGBに全く同じ値が入っていて,
これにConvolutionFilterをかけるのは,3倍冗長な処理を行ってる事になる.
ので,電界マップの上中下段を3分割して,それぞれをRGBにコピーした
1/3の大きさの画像に対して,ConvolutionFilterをかければ良い.これで1.6倍速位.
最適化ってほどではないけど,3倍のConvolutionFilterってのは,
あまりにも冗長だし,明らかなボトルネックなので修正.
以下追加ソース.
ライセンスはPublic Domainです
public class main_ref_fast extends Sprite { ...追加 static private var base3:BitmapData; // 1/3 base image static private var rc:Rectangle = new Rectangle(); // multipurpose static private var pt:Point = new Point(); // multipurpose static private var tmp3x:BitmapData; // multipurpose 1/3 bitmap static private var tmp3y:BitmapData; // multipurpose 1/3 bitmap ... public function main_ref_fast() { ... 追加 base3 = new BitmapData(240, 82, false); tmp3x = new BitmapData(240, 82, false); tmp3y = new BitmapData(240, 82, false); ... } private function _onEnterFrame(event:Event) : void { var i:int, j:int; // measure start //var start:int = getTimer(); for (var l:int=0; l<100; l++) { // execute ball.mouseX = mouseX; ball.mouseY = mouseY; for (i=0; i<balls.length; i++) { ball(balls[i]).gravity(); } for (i=0; i<balls.length-1; i++) for (j=i+1; j<balls.length; j++) { ball(balls[i]).interact(ball(balls[j])); } for (i=0; i<balls.length; i++) { ball(balls[i]).run(); } calcBallCenter(); // draw balls base.fillRect(pixels.rect,0x000000); for (i=0; i<balls.length; i++) { ball(balls[i]).draw(base); } // divide by 3 rc.width = 240; rc.height = 82; rc.x = 0; rc.y = -1; base3.copyChannel(base, rc, base3.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.RED); rc.y = 79; base3.copyChannel(base, rc, base3.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.GREEN); rc.y = 159; base3.copyChannel(base, rc, base3.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.BLUE); // refraction /* // original temp.applyFilter(base, base.rect, base.rect.topLeft, convx); bump.applyFilter(base, base.rect, base.rect.topLeft, convy); bump.copyChannel(temp, temp.rect, temp.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.RED); temp.applyFilter(floor, floor.rect, floor.rect.topLeft, disp); alph.copyPixels(temp, temp.rect, temp.rect.topLeft); */ tmp3x.applyFilter(base3, base3.rect, base3.rect.topLeft, convx); tmp3y.applyFilter(base3, base3.rect, base3.rect.topLeft, convy); rc.width = 240; rc.height = 80; rc.x = 0; rc.y = 1; pt.x = 0; pt.y = 0; bump.copyChannel(tmp3x, rc, pt, BitmapDataChannel.RED, BitmapDataChannel.RED); pt.y = 80; bump.copyChannel(tmp3x, rc, pt, BitmapDataChannel.GREEN, BitmapDataChannel.RED); pt.y = 160; bump.copyChannel(tmp3x, rc, pt, BitmapDataChannel.BLUE, BitmapDataChannel.RED); pt.y = 0; bump.copyChannel(tmp3y, rc, pt, BitmapDataChannel.RED, BitmapDataChannel.GREEN); pt.y = 80; bump.copyChannel(tmp3y, rc, pt, BitmapDataChannel.GREEN, BitmapDataChannel.GREEN); pt.y = 160; bump.copyChannel(tmp3y, rc, pt, BitmapDataChannel.BLUE, BitmapDataChannel.GREEN); temp.applyFilter(floor, floor.rect, floor.rect.topLeft, disp); alph.copyPixels(temp, temp.rect, temp.rect.topLeft); // lighting /* // original temp.applyFilter(base, base.rect, base.rect.topLeft, conv); alph.draw(temp,null,null,BlendMode.HARDLIGHT); */ tmp3x.applyFilter(base3, base3.rect, base3.rect.topLeft, conv); pt.y=0; temp.copyChannel(tmp3x, rc, pt, BitmapDataChannel.RED, BitmapDataChannel.RED); pt.y=80; temp.copyChannel(tmp3x, rc, pt, BitmapDataChannel.GREEN, BitmapDataChannel.RED); pt.y=160; temp.copyChannel(tmp3x, rc, pt, BitmapDataChannel.BLUE, BitmapDataChannel.RED); temp.copyChannel(temp, temp.rect, temp.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.GREEN); temp.copyChannel(temp, temp.rect, temp.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.BLUE); alph.draw(temp,null,null,BlendMode.HARDLIGHT); // cutout /* // original temp.copyPixels(base, base.rect, base.rect.topLeft); temp.colorTransform(temp.rect, colt); alph.copyChannel(temp, temp.rect, temp.rect.topLeft, BitmapDataChannel.RED, BitmapDataChannel.ALPHA); */ base3.colorTransform(base3.rect, colt); pt.y=0; alph.copyChannel(base3, rc, pt, BitmapDataChannel.RED, BitmapDataChannel.ALPHA); pt.y=80; alph.copyChannel(base3, rc, pt, BitmapDataChannel.GREEN, BitmapDataChannel.ALPHA); pt.y=160; alph.copyChannel(base3, rc, pt, BitmapDataChannel.BLUE, BitmapDataChannel.ALPHA); // draw pixels.copyPixels(floor, floor.rect, floor.rect.topLeft); pixels.copyPixels(alph, alph.rect, alph.rect.topLeft); drawFace(); // measure end //} trace(getTimer() - start); } ... 後は一緒 }