2012-08-29 14 views
6

tengo el siguiente código, hecha solo para probar, ya que era una especie de un insecto que quería clavar:La aplicación del filtro de sombreado a un objeto BitmapData ignora el rectángulo pasado: ¿cómo aplicar correctamente el filtro de sombreado?

 _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); 
     } 

Entonces ciclo a través de _sequence con el fin de ver si el cambio rectángulo realmente hace algo. No hace nada, si _shaderFilter es en realidad un filtro de sombreado. Las pruebas con cualquiera de los filtros de flash incorporados funcionan según lo previsto, pero con ShaderFilter a veces funciona como si el rectángulo suministrado fuera simplemente sourceBitmapData.rect, cualquiera que sea el mapa de bits de origen, y algunas veces se comporta como si no hubiera datos pasados, siendo el límite ubicado en una posición extraña: con un mapa de bits de tamaño 512x384, el borde de la región que se pasa al sombreador está aparentemente ubicado en (256,192) o en el centro del mapa de bits. Hasta ahora, solo pude implementar una solución alternativa, es decir, copiar primero Pixel() la región requerida y luego aplicar Filter() en su lugar. ¿Puede alguien probar que es un error y que yo no estoy haciendo algo mal?

PD: Estoy usando FlashDevelop con el objetivo del proyecto siendo Flash Player 10.3, y no estoy al tanto de si el FP11 corrige esto.

Respuesta

1

Bueno, lamentablemente no puedo decirle cómo solucionar esto, pero puedo confirmar que ¡no es su culpa!

El problema parece ser que Flash ignora por completo sourceRect al usar sombreadores personalizados. Al principio pensé que podría estar pasando los valores a un parámetro no documentado en el sombreador, pero luego noté que cada píxel del mapa de bits de salida se cambia, incluso cuando el sourceRect es más pequeño o el destPoint no es cero. Además, no parece haber una función inCoord() que coincida con outCoord(), por lo que parece que este no es un uso que los desarrolladores esperaban.

Puedo ofrecer una sugerencia; en lugar de copiar el ROI a un nuevo objeto BitmapData, agregue un parámetro float2 offset a su sombreador y cambie todas las búsquedas de píxeles por este valor. Se ahorrará algo de procesamiento.

Aquí es el caso de ensayos simplificado he usado para confirmar el comportamiento:

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()); 
    } 
} 

Salida:

Screenshot of output

(el cuadrado pequeño de la derecha copia del cuadrado grande usando un sombreador. El cuadro rojo muestra sourceRect. El destPoint es (10,10). A pesar de estas dos configuraciones, en realidad representa todo el mapa de bits)

+0

¡Gracias por intentar una prueba independiente! ¿Intentó compilarlo con el objetivo de FP11 y comprobar si funciona igual allí? – Vesper

+1

@Vesper Sí, lo probé en 10 y 11. El mismo resultado en ambos (la captura de pantalla es de 11) – Dave

Cuestiones relacionadas