pixelBenderでズームブラー/スピンブラーフィルター作ってみました。

すでにいろんな人がやってるようですが、
PixelBenderの勉強も兼ねてやってみました。


通常のブラーと同様、複数の画素から色をサンプリングして
サンプリング数で割る形で、各画素の色を決定していきます。

サンプリングする幅でブラーの強度、点の数でブラーの品質を決め、
サンプリングする幅はブラーの中心点からの距離に比例して増やしていきました。


 ズームブラー

image_zoom.jpg

 
  スピンブラー

image_spin.jpg



ブラーの品質についてですが、サンプリング数を128個くらいまで増やすと
とても綺麗にブラーがかかってくれていたのですが、
いざFlash上でフィルターとして使ってみると、実用に耐え難い実行速度に。
10個くらいまで減らすことでなんとか実用に耐えうる速度が出ました。


ZoomBlur.pbj

ソースは以下のような感じ。多分もっと最適化出来る気がします。

<languageVersion: 1.0;>

kernel ZoomBlur

<namespace : "";
vendor : "Shimada Kousho";
version : 1;
description : "zoom/spin blur";>

{
    input image4 src;
    output float4 dst;
    
    parameter float2 center
    <
        minValue:float2(0.0);
        maxValue:float2(2800.0);
    >;
    
    parameter float strength
    <
        minValue:0.0;
        maxValue:1.0;
        defaultValue:0.0;
    >;
    
    parameter int spin
    <
        minValue:0;
        maxValue:1;
        defaultValue:0;
    >;
   
    void evaluatePixel()
    {
        float2 pos = outCoord();
        float2 delta = pos - center;
        float2 range;
        
        if(spin == 0)
        {
            range = delta;
        }
        else
        {
            range.x = delta.y;
            range.y = - delta.x;
        }
        
        range *= strength;
        
        float4 color = sampleNearest(src, pos);
        
        color += sampleNearest(src, pos + range / 4.0);
        color += sampleNearest(src, pos + range / 2.0);
        color += sampleNearest(src, pos + range * 3.0 / 4.0);
        color += sampleNearest(src, pos + range);
        
        color += sampleNearest(src, pos - range / 4.0);
        color += sampleNearest(src, pos - range / 2.0);
        color += sampleNearest(src, pos - range * 3.0 / 4.0);
        color += sampleNearest(src, pos - range);
       
        dst = color / 9.0;
    }
}


強度を0~1まで設定出来るようにしてありますが、サンプリングの点を10個まで減らしたことで、
実際に綺麗にブラーがかかって見えるのは画像の大きさにもよりますが、0~0.1くらいです。  

次のエントリーでは、実際にPixelBenderをやってみて気づいた点とか書こうと思います。

HTML5飯