6

これは私が釘付けにしたい一種のバグだったので、テスト専用に作成された次のコードがあります。

        _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 でこれが修正されるかどうかはわかりません。

4

1 に答える 1

1

残念ながら、これを修正する方法をお伝えすることはできませんが、あなたのせいではないことを確認できます!

sourceRect問題は、カスタム シェーダーを使用するときに Flash が完全に無視することです。最初は、シェーダーの文書化されていないパラメーターに値を渡しているのではないかと考えていましたが、出力ビットマップのすべてのピクセルが、sourceRectより小さい場合やdestPointゼロでない場合でも変更されることに気付きました。また、inCoord()に一致する関数outCoord()がないように見えるため、これは開発者が期待した用途ではないようです!

1 つ提案できます。ROI を新しいBitmapDataオブジェクトにコピーする代わりに、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());
    }
}

出力:

出力のスクリーンショット

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

于 2013-04-04T21:41:09.383 に答える