2012-08-29 10 views
6

これは私が爪たかったバグのようなものだったように私は、テストのためだけに作られた以下のコードを、持っている:BitmapDataオブジェクトにシェーダフィルタを適用すると、渡された矩形が無視されます。シェーダフィルタを正しく適用する方法は?

 _shader = new Shader(new TheShader() as ByteArray); 
     _shader.data.width.value = [64.0]; 
     _shader.data.height.value = [64.0]; 
     _shaderFilter = new ShaderFilter(_shader); 
     _sequence = new Vector.<BitmapData>(); 
     var smallBD:BitmapData; 
     var i:int; 
     _delta = new Point(); 
     var megabase:BitmapData = new TheBitmap().bitmapData; 
     var _rect:Rectangle = new Rectangle(0, 0, 64, 64); 
     for (i = 0; i < 64; i++) { 
      smallBD = new BitmapData(64, 64, true, 0x00808080); 
      //_rect.x = i; 
      _rect.y = i; 
      smallBD.applyFilter(megabase, _rect, _delta, _shaderFilter); 
      _sequence.push(smallBD); 
     } 

_sequenceてそれから私サイクル変更矩形が実際に何かをするかどうかを確認するために。 _shaderFilterが実際にシェーダフィルタであれば、何もしません。組み込みのFlashフィルタを使ったテストは意図したとおりに動作しますが、ShaderFilterでは、供給された矩形がsourceBitmapData.rectであるかのように動作することがありますが、ソースビットマップが何であれ、奇妙な位置にあります - サイズ512x384のビットマップでは、シェーダに渡される領域の端は明らかに(256,192)またはビットマップの中央にあります。これまでは回避策を実装することしかできませんでした。つまり、必要な領域を最初にcopyPixels()した後、applyFilter()を実行します。誰かがそれがバグだと私に何か間違っていることを証明することはできますか?

PS:Flash Player 10.3のプロジェクトターゲットでFlashDevelopを使用していますが、FP11でこれを修正してもわかりません。

答えて

1

悲しいことに、これを修正する方法を教えてもらえませんが、あなたの責任ではないことを確認できます。

カスタムシェイダーを使用すると、Flashは完全にsourceRectを無視しているようです。最初はシェーダのパラメータが不明なパラメータに値を渡していると思っていましたが、sourceRectが小さくてもdestPointが0でなくても、出力ビットマップのすべてのピクセルが変更されていることに気付きました。またoutCoord()と一致するようにinCoord()関数が存在しないようですので、これは開発者の期待通りの使用ではないようです。

私は1つの提案を提供できます。新しいBitmapDataオブジェクトにROIをコピーする代わりに、float2 offsetパラメータをシェーダに追加し、すべてのピクセルルックアップをこの値でシフトします。いくつかの処理が節約されます。ここで

は私が行動を確認するために使用削減テストケースです:

ShaderTest.as:

package { 
    import flash.display.Sprite; 
    import flash.display.Bitmap; 
    import flash.display.BitmapData; 
    import flash.display.Shader; 
    import flash.geom.Point; 
    import flash.geom.Rectangle; 
    import flash.filters.ShaderFilter; 

    final public class ShaderTest extends Sprite { 
     [Embed(source="test.pbj",mimeType="application/octet-stream")] 
     private static const sCopy : Class; 

     final private function R(x, y, w, h) : Rectangle { 
      return new Rectangle(x, y, w, h); 
     } 
     final public function ShaderTest() { 
      super(); 
      var 
      s : Shader = new Shader(new sCopy()), 
      f : ShaderFilter = new ShaderFilter(s), 
      d1 : BitmapData = new BitmapData(256, 256, false, 0), 
      d2 : BitmapData = new BitmapData(128, 128, false), 
      b1 : Bitmap = new Bitmap(d1), 
      b2 : Bitmap = new Bitmap(d2), 
      w : Rectangle = R(16, 16, 64, 64); 
      b2.x = 274; 
      addChild(b1); 
      addChild(b2); 

      for(var i : int = 0; i < 8; ++ i) { 
       for(var j : int = 0; j < 8; ++ j) { 
        d1.fillRect(R(i * 32 + 1, j * 32 + 1, 30, 30), (((i + j) & 1) * 0x00FF00) | (i << 21) | (j << 5)); 
       } 
      } 
      d2.applyFilter(d1, w, new Point(10, 10), f); 
      d1.fillRect(R(w.x, w.y, 1, w.height), 0xFF0000); 
      d1.fillRect(R(w.x, w.y, w.width, 1), 0xFF0000); 
      d1.fillRect(R(w.x, w.y + w.height - 1, w.width, 1), 0xFF0000); 
      d1.fillRect(R(w.x + w.width - 1, w.y, 1, w.height), 0xFF0000); 
     } 
    } 
} 

test.pbk:

<languageVersion:1.0;> 

kernel bugtest <namespace:"Me";vendor:"Me";version:1;>{ 
    input image4 src; 
    output pixel4 dst; 
    void evaluatePixel(){ 
     dst = sampleNearest(src,outCoord()); 
    } 
} 

出力:

Screenshot of output

(右側の小さな正方形は、シェイダーを使用して大きな正方形からコピーします。赤いボックスにはsourceRectが表示されます。 destPointは(10,10)です。これらの設定にもかかわらず、実際にはビットマップ全体がレンダリングされます)

+0

お試しいただきありがとうございます! FP11ターゲットでコンパイルしてみて、それが同じで動作するかどうかチェックしましたか? – Vesper

+1

@Vesperはい、私は10と11でそれを試しました。両方で同じ結果(スクリーンショットは11からです) – Dave

関連する問題