使用Pixel Bender 和Shader Job来处理普通数据运算 [转]
虽然Pixel Bender主要是用来处理图形任务,但他还有一个强大的用法-处理普通数据(generic number crunching)。Pixel Bender核心和ActionScript在不同的进程中运行,你可以利用这个特点来避免界面的假死(无响应)。提高复杂运算的速度。例如,我们在处理一个很大规模的数据集合,需要对每个数据进行复杂的数学计算(3D,声音引擎等等)。你可以使用Pixel Bender kernal来处理这些数据,最后再将处理好的数据交给AS代码,效果好的甚至会超过优化的很好的AS代码。
下面是个非常简单的例子,Pixel Bender kernel接受一个数组,然后返回一个包含源数组的平方根的新数组。
CODE:- <languageVersion : 1.0;>
- kernel NumberCruncher
- <
- namespace : "AIF";
- vendor : "Ryan Taylor";
- version : 1;
- description : "Basic example of a generic number cruncher.";
- >
- {
- input image1 src;
- output pixel3 result;
- void evaluatePixel()
- {
- pixel1 value = pixel1(sqrt(sample(src, outCoord())));
- result = pixel3(value, 0.0, 0.0);
- }
- }
- package
- {
- import flash.display.Shader;
- import flash.display.ShaderJob;
- import flash.display.Sprite;
- import flash.events.Event;
- import flash.utils.ByteArray;
- import flash.utils.Endian;
- public class Main extends Sprite
- {
- protected var _shader:Shader;
- protected var _shaderJob:ShaderJob;
- protected var _input:ByteArray;
- protected var _output:ByteArray;
- [Embed(source="/../assets/filters/NumberCruncher.pbj", mimeType="application/octet-stream")]
- protected var NumberCruncher:Class;
- public function Main()
- {
- init();
- }
- protected function init():void
- {
- _input = new ByteArray();
- _input.endian = Endian.LITTLE_ENDIAN;
- _input.writeFloat(4);
- _input.writeFloat(16);
- _input.writeFloat(100);
- _input.writeFloat(400);
- _input.position = 0;
- var int = _input.length >> 2;
- var height:int = 1;
- _shader = new Shader(new NumberCruncher());
- _shader.data.src.width = width;
- _shader.data.src.height = height;
- _shader.data.src.input = _input;
- _output = new ByteArray();
- _output.endian = Endian.LITTLE_ENDIAN;
- _shaderJob = new ShaderJob(_shader, _output, width, height);
- _shaderJob.addEventListener(Event.COMPLETE, onShaderJobComplete, false, 0, true);
- _shaderJob.start();
- }
- protected function onShaderJobComplete(event:Event):void
- {
- _output.position = 0;
- var length:int = _output.length;
- for(var i:int = 0; i < length; i += 4)
- {
- var output:Number = _output.readFloat();
- if(i % 3 == 0)
- trace("value -> " + output);
- }
- }
- }
- }
为了解决我早先提到的三通道输出的问题,我使用了取模的运算,在“onShaderJobComplete”方法中,最终结果是所有输入数字的平方根。
所以那是很好的。可以想象,等这些bug都消除以后,这江是个非常有用的东西。