
以前紹介したバンプマッピングのPixel BenderをFlashで使おうとしてみたのですが、なぜかうまくいきませんでした・・・。
真っ黒でなにもでなかったり、明らかにおかしな色になってしまったのです。その際、色々試した結果をここでちょっと報告したいと思います。
まずは、上の画像がいったいなんなのかを説明します。
outCoord()の値を可視化する
上の画像は、outCoord()の値からx座標の値をR成分に、y座標の値をG成分にしたものです。
これには、以下のPixel Benderのコードを使っています。
<languageVersion : 1.0;>
kernel SampleFilter
< namespace : "jp.flup";
vendor : "Flup Inc.";
version : 1;
description : "outCoord test filter";
>
{
input image4 src;
output pixel4 dst;
void
evaluatePixel()
{
dst.r = (outCoord().x-100.0)/200.0;
dst.g = (100.0-outCoord().y)/200.0;
dst.b = 0.0;
dst.a = 1.0;
}
}
これは、Pixel Bender Toolkit で生成した画像を出力したもので、Flashはこの時点では関係ありません。
ShaderFilterの適用
次に、ShaderFilterで単一の入力イメージに対してフィルタを適用してみます。これはActionScriptになります。
package {
import flash.display.*;
import flash.filters.*;
public class filter_test extends Sprite
{
[Embed(source="test.pbj", mimeType="application/octet-stream")]
private static var ShaderByteCode:Class;
[Embed(source="dummy.jpg")]
private static var Image1:Class;
private var bmp1:Bitmap;
public function filter_test()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
bmp1 = new Image1() as Bitmap;
addChild(bmp1);
var shader:Shader = new Shader(new ShaderByteCode());
bmp1.filters = [new ShaderFilter(shader)];
}
}
}
実行すると、左のようになります。これは実際作成したswfファイルになっています。
最初の生成画像と全く同じになっていることが分かります。
blendShaderにすると・・・
次に、2枚の画像に対してブレンドモードでShaderを適用してみます。フィルタも若干(といっても入力を増やすだけですが)変更します。
<languageVersion : 1.0;>
kernel SampleFilter
< namespace : "jp.flup";
vendor : "Flup Inc.";
version : 1;
description : "outCoord test filter";
>
{
input image4 src;
input image4 src2;
output pixel4 dst;
void
evaluatePixel()
{
dst.r = (outCoord().x-100.0)/200.0;
dst.g = (100.0-outCoord().y)/200.0;
dst.b = 0.0;
dst.a = 1.0;
}
}
このようにして、入力画像を2つ使うことができるようにします(実際使ってはいませんが・・)。
次に、ActionScript側も入力画像を2つ使ってblendShaderを指定するように変更します。
package {
import flash.display.*;
import flash.filters.*;
public class filter_test extends Sprite
{
[Embed(source="test.pbj", mimeType="application/octet-stream")]
private static var ShaderByteCode:Class;
[Embed(source="dummy.jpg")]
private static var Image1:Class;
private var bmp1:Bitmap;
private var bmp2:Bitmap;
public function filter_test()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
bmp1 = new Image1() as Bitmap;
addChild(bmp1);
bmp2 = new Image1() as Bitmap;
addChild(bmp2);
var shader:Shader = new Shader(new ShaderByteCode());
bmp2.blendMode = BlendMode.SHADER;
bmp2.blendShader = shader;
}
}
}
実際には入力画像はつかっておらず、outCoord()の値のみで出力画像を生成しているので、結果は以前と変わらないはずですが・・・。
このように、緑色のベタ塗りになってしまいました・・・。最初の画像と異なっているのは一目瞭然ですね。
どういうことなのか?
これが仕様なのかバグなのかは私には分かりませんし、私の方法が悪いのかもしれませんが、blendShaderでpbjを使うと、outCoord()が出力ピクセル毎に(ほぼ)同じ値になってしまうようです。ほぼ、と書いたのは全く同じかどうか確認することができず、座標系が異なっている可能性もあるので・・。
ただ、Pixel Benderでは1ピクセルにつき座標を1増減するつもりで記述している(し、Pixel Bender Toolkitではそれで問題なく動作を確認している)ので、outCoord()の値によってピクセル値を制御することをblendShaderでやりたい場合は今回のような問題が発生しそうです。
一体これはどういうことなんでしょうね?どなたか原因が分かる方いらっしゃったらお教えください・・・。
