• 使用Pixel Bender 和Shader Job来处理普通数据运算


    使用Pixel Bender 和Shader Job来处理普通数据运算 [转]

    虽然Pixel Bender主要是用来处理图形任务,但他还有一个强大的用法-处理普通数据(generic number crunching)。Pixel Bender核心和ActionScript在不同的进程中运行,你可以利用这个特点来避免界面的假死(无响应)。提高复杂运算的速度。例如,我们在处理一个很大规模的数据集合,需要对每个数据进行复杂的数学计算(3D,声音引擎等等)。你可以使用Pixel Bender kernal来处理这些数据,最后再将处理好的数据交给AS代码,效果好的甚至会超过优化的很好的AS代码。

    下面是个非常简单的例子,Pixel Bender kernel接受一个数组,然后返回一个包含源数组的平方根的新数组。

    CODE:
    1. <languageVersion : 1.0;>
    2. kernel NumberCruncher
    3. <
    4. namespace : "AIF";
    5. vendor : "Ryan Taylor";
    6. version : 1;
    7. description : "Basic example of a generic number cruncher.";
    8. >
    9. {
    10. input image1 src;
    11. output pixel3 result;
    12. void evaluatePixel()
    13. {
    14. pixel1 value = pixel1(sqrt(sample(src, outCoord())));
    15. result = pixel3(value, 0.0, 0.0);
    16. }
    17. }
    首先,注意结果是通过一个三元的pixel值返回回来的。当输出值低于三元的时候,目前版本的Pixel Bender工具,会抛出一个错误,并且拒绝生成字节码。Pixel Bender细则中描述是支持pixel1,pixel2,pixel3,pixel4输出的,所以这可能是一个Pixel Bender工具的bug。为了解决这个问题,我将后两个元素设置为0。同样,输入的类型必须为image1。 在AS段,需要如下处理:1.创建一个ByteArray对象,使用writeFloat方法来天津每个数据,确保endian设置为little endian。细则中虽说Vector.<Number>类型可以作为shader的输入数据,但是在使用这种方法的时候同样也出现了bug。2.创建一个Shader实例来接受Pixel Bender的字节码。宽度根据你的数据数组的长度来获取。在ByteArray中,你需要将数组长度除以4。高度你只需要设置为1。input必须为一个集合。3.创建一个ByteArray来储存shader计算的结果。同样确保endian为little endian。4.创建一个ShaderJob实例类接受shader,设置好输入,高度,宽度几个参数,添加一个"complete"的监听,等Shader计算结束后,来处理输出的ByteArray。然后你可以使用start方法来执行shader。这是as的代码示例:
    1. package
    2. {
    3. import flash.display.Shader;
    4. import flash.display.ShaderJob;
    5. import flash.display.Sprite;
    6. import flash.events.Event;
    7. import flash.utils.ByteArray;
    8. import flash.utils.Endian;
    9. public class Main extends Sprite
    10. {
    11. protected var _shader:Shader;
    12. protected var _shaderJob:ShaderJob;
    13. protected var _input:ByteArray;
    14. protected var _output:ByteArray;
    15. [Embed(source="/../assets/filters/NumberCruncher.pbj", mimeType="application/octet-stream")]
    16. protected var NumberCruncher:Class;
    17. public function Main()
    18. {
    19. init();
    20. }
    21. protected function init():void
    22. {
    23. _input = new ByteArray();
    24. _input.endian = Endian.LITTLE_ENDIAN;
    25. _input.writeFloat(4);
    26. _input.writeFloat(16);
    27. _input.writeFloat(100);
    28. _input.writeFloat(400);
    29. _input.position = 0;
    30. var int = _input.length >> 2;
    31. var height:int = 1;
    32. _shader = new Shader(new NumberCruncher());
    33. _shader.data.src.width = width;
    34. _shader.data.src.height = height;
    35. _shader.data.src.input = _input;
    36. _output = new ByteArray();
    37. _output.endian = Endian.LITTLE_ENDIAN;
    38. _shaderJob = new ShaderJob(_shader, _output, width, height);
    39. _shaderJob.addEventListener(Event.COMPLETE, onShaderJobComplete, false, 0, true);
    40. _shaderJob.start();
    41. }
    42. protected function onShaderJobComplete(event:Event):void
    43. {
    44. _output.position = 0;
    45. var length:int = _output.length;
    46. for(var i:int = 0; i < length; i += 4)
    47. {
    48. var output:Number = _output.readFloat();
    49. if(i % 3 == 0)
    50. trace("value -> " + output);
    51. }
    52. }
    53. }
    54. }

    为了解决我早先提到的三通道输出的问题,我使用了取模的运算,在“onShaderJobComplete”方法中,最终结果是所有输入数字的平方根。

    所以那是很好的。可以想象,等这些bug都消除以后,这江是个非常有用的东西。

  • 相关阅读:
    【转-整理】win764bit plsql 登录oracle11g ora-12154 问题汇总
    【转-整理】log4j 简单解释,配置
    sparsity and density
    转:Recsys2013论文导读
    学院研究生论坛-如何做研究
    推荐系统开源软件列表
    linux下如何用GDB调试c++程序
    全国大学生数据挖掘邀请赛中的NDCG
    网络科学自学资料
    科普文:从人人网看网络科学(Network Science)的X个经典问题
  • 原文地址:https://www.cnblogs.com/hisiqi/p/2840835.html
Copyright © 2020-2023  润新知