1 Reply Latest reply on Jun 13, 2012 5:47 AM by rawhedrawhed

    sampleLinear doesn't work when scaling outCoord using ByteArray or Vector.<Number>

    rawhedrawhed Level 1

      Hi,

       

      I think I've found a bug in Pixel Bender that's so far been missed.

       

      If you want to upsample a buffer using a ShaderJob and ByteArray/Vector.<Number> it doesn't work with sampleLinear, only sampleNearest.  Using sampleLinear it returns a buffer with mostly black pixels but with every 2nd pixel (for upsampling to a double sized buffer) written to.  So basically it looks like it's upsampling but only writing to some of the target pixels...

       

      Btw, I'm talking about in Flash here.   And I need to use ByteArray/Vector.<Number> instead of BitmapData as I need to process 32-bit data.

       

      Strangely it works in the PB toolkit in all of the modes (GPU, CPU, Flash).

       

      Am I doing something wrong or is this a known issue?

       

      Here's my sample code:

       

      package 

      {

                import flash.display.Bitmap;

                import flash.display.BitmapData;

                import flash.display.Shader;

                import flash.display.ShaderJob;

                import flash.display.ShaderPrecision;

                import flash.display.Sprite;

                import flash.display.StageQuality;

                import flash.geom.Vector3D;

                import flash.utils.ByteArray;

                import flash.utils.Endian;

                import flash.utils.Timer;

       

                public class Test_Upscale extends Sprite

                {

                          [Embed ( source = "../data/embed/pixelbender/bilinearresample.pbj", mimeType = "application/octet-stream" ) ]

                          private var BilinearScalingKernel:Class;

       

                          public function Test_Upscale()

                          {

                                    const srcWidth:int = 256;

                                    const srcHeight:int = 256;

                                    const dstWidth:int = 256;

                                    const dstHeight:int = 256;

       

                                    this.stage.quality = StageQuality.BEST;

       

                                    // Create noise input buffer

                                    var input:ByteArray = new ByteArray();

                                    input.endian = Endian.LITTLE_ENDIAN;

                                    input.length = srcWidth * srcHeight * 4 * 4;

                                    for (var i:int = 0; i < srcWidth*srcHeight; i++)

                                    {

                                              var val:int = Math.random() * 255.0;

                                              input.writeFloat(val);

                                              input.writeFloat(val);

                                              input.writeFloat(val);

                                              input.writeFloat(255.0);

                                    }

                                    input.position = 0;

       

                                    // Create output buffer

                                    var output:ByteArray = new ByteArray();

                                    output.endian = Endian.LITTLE_ENDIAN;

                                    output.length = dstWidth * dstHeight * 4 * 4;

       

       

                                    // Resample

                                    Resample(input, srcWidth, srcHeight, dstWidth, dstHeight, output);

       

                                    // Display as a bitmap

                                    this.addChild(new Bitmap(ToBitmap(dstWidth, dstHeight, output) ));

                          }

       

                          private static function ToBitmap(width:int, height:int, data:ByteArray):BitmapData

                          {

                                    data.position = 0;

       

                                    var bmp:BitmapData = new BitmapData(width, height, false);

                                    var idx:int = 0;

                                    for (var j:int = 0; j < height; j++)

                                    {

                                              for (var i:int = 0; i < width; i++)

                                              {

                                                        var r:int = data.readFloat() as int;

                                                        var g:int = data.readFloat() as int;

                                                        var b:int = data.readFloat() as int;

                                                        data.readFloat();

                                                        var c:int = r + (g << 8) + (b << 16);

                                                        bmp.setPixel(i, j, c);

                                                        idx++;

                                              }

                                    }

       

                                    return bmp;

                          }

       

                          public function Resample(src:ByteArray, srcWidth:int, srcHeight:int, dstWidth:int, dstHeight:int, dst:ByteArray):void

                          {

                                    // create and configure a Shader object

                                    var shader:Shader = new Shader();

                                    shader.precisionHint =ShaderPrecision.FULL;

                                    shader.byteCode = new BilinearScalingKernel();

                                    shader.data.src.input = src;

                                    shader.data.src.width = srcWidth;

                                    shader.data.src.height = srcHeight;

                                    shader.data.scaley.value = [0.5];

       

       

                                    var job:ShaderJob = new ShaderJob(shader, dst, dstWidth, dstHeight);

       

                                    job.start(true); // true flag runs the job synchronously.

                          }

                }

      }

       

       

       

       

       

      <languageVersion : 1.0;>

      kernel BilinearResample

      <   namespace : "com.test.pixelbender";

          vendor : "me";

          version : 1;

          description : "bilinear";

      >

          input image4 src;

          output pixel4 dst;

         

          parameter float scaley;

         

          void

          evaluatePixel()

          {

              dst = sampleLinear(src, outCoord() * float2(scaley, scaley)); // bilinear scaling

          }

      }