5

我有一个关于像素弯曲器的性能问题。我想放大许多 BitmapData(将它们的大小加倍为新的 BitmapData)。我用 as3 做这个,但想使用像素弯曲器来获得更好的性能。在我的机器上,我从像素弯曲器演示中获得了比as3更好的性能。

令我惊讶的是(或糟糕的编码/理解),我从像素弯曲器中获得了更差的性能——2 秒对 1/2 秒!我希望获得至少与as3 相同的性能。我究竟做错了什么?

我在这里得到了简单的像素弯曲代码(它包含在下面以便于参考)。

package
{

import flash.display.BitmapData;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Matrix;

public class flashFlash extends Sprite
{


[Embed ( source="pixelbender/bilinearresample.pbj", mimeType="application/octet-stream" ) ]
private static var BilinearScaling:Class;

public function flashFlash( ):void
{
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    addEventListener( Event.ENTER_FRAME, efCb, false, 0, true );
}

private function efCb( evt:Event ):void
{
    removeEventListener( Event.ENTER_FRAME, efCb, false );

    traceTime( "init" );

    var srcBmd:BitmapData = new BitmapData( 80, 120, false, 0 );
    var destBmd:BitmapData = new BitmapData( 160, 240, false, 0 );

    var mx:Matrix = new Matrix( );
    mx.scale( 2, 2 );
    for (var i:uint = 0; i < 3000; i++)
    {   destBmd.draw( srcBmd, mx );
    }

    traceTime( "scaled with as3" );

    // create and configure a Shader object
    var shader:Shader = new Shader( );
    shader.byteCode = new BilinearScaling( );
    shader.data.scale.value = [.5];
    shader.data.src.input = srcBmd;

    for (var j:uint = 0; j < 3000; j++)
    {
        var shaderJob:ShaderJob = new ShaderJob( );
        shaderJob.shader = shader;
        shaderJob.target = destBmd;
        shaderJob.start( true );
    }

    traceTime( "scaled with pixel bender bilinearresample.pbj" );
}

private static var _lastTraceTime:Number = new Date().getTime();
public static function traceTime( note:String ):Number
{   var nowTime:Number = new Date().getTime();
    var diff:Number = (nowTime-_lastTraceTime);
    trace( "[t" + diff + "] " + note );
    _lastTraceTime = nowTime;
    return diff;
}

}
}

和像素弯曲代码:

<languageVersion : 1.0;>

kernel BilinearResample
<   namespace : "com.brooksandrus.pixelbender";
    vendor : "Brooks Andrus";
    version : 1;
    description : "Resizes an image using bilinear resampling. Constrains aspect ratio - divide Math.max( input.width / output.width, input.height / output.height ) and pass in to the scale parameter";
>
{
    parameter float scale
    <
        minValue: 0.0;
        maxValue: 1000.0;
        defaultValue: 1.0;
    >;

    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        // scale should be Math.max( src.width / output.width, src.height / output.height )
        dst = sampleLinear( src, outCoord() * scale ); // bilinear scaling
    }
}
4

2 回答 2

8

我认为问题在于您实际上是在将 Pixel Bender 与本机播放器代码进行比较,而不是与“动作脚本”进行比较。我怀疑 Pixel Bender 是否会在这种情况下获胜。

此处发生的缩放destBmd.draw( srcBmd, mx );直接在播放器中编码;这可能是您所能获得的最快速度(使用等效算法)。另一方面,您的内核至少必须先编译(或 JIT 编译)才能运行(可能有许多其他原因导致它变慢;不过,我不太了解具体细节)。

从Flash Player 工程师的博客中查看这篇文章:

很久以前,早在 Flash Player 8 天之前,我们就有了添加一种通用方法来执行位图过滤器的想法。像我们为 Flash Player 8 所做的硬编码位图过滤器不仅不灵活,而且还需要向播放器中添加大量本机代码,并且必须针对每个平台对其进行优化。对我们来说,问题一直是您将如何创作此类通用过滤器。各种想法四处流传,但最终有一个症结所在:我们没有语言,也没有编译器。在 Macromedia 与 Adob​​e 合并后,Flash Player 和 Adob​​e Pixel Bender 团队走到了一起,我们终于有了我们需要的东西:一种语言和一个编译器。

因此,基本上,Pixel Bender 比直接在 Actionscript 中处理像素要快。它将胜过相当数量的 setPixel 和 getPixel 调用。但它不会比玩家本身更快(同样,使用相同的算法)。

在某种程度上,你想做的就像在 PB 中编写一个发光滤镜。当然,它很酷,如果您对图像处理感兴趣,您可以从中学到很多东西。但是,如果您的过滤器旨在像原生过滤器一样工作,那么除了教育目的之外,它没有什么意义:原生过滤器会更快并且它已经可用,无需额外的代码行。

于 2010-05-18T01:44:13.597 回答
2

我隐约记得听说虽然连接到像素弯曲文件等的过程较慢,但处理本身却更快。所以我想你会看到随着图像尺寸变大,像素弯曲过滤器最终可能会变得更有效。或者也许 PixelBender 最好保存用于稍微复杂的图像处理。

于 2010-05-18T01:06:44.563 回答