Uso de um sombreador como um preenchimento de desenho

Flash Player 10 e posterior, Adobe AIR 1.5 e posterior

Ao usar um sombreador para criar um preenchimento de desenho, você deve utilizar os métodos de API de desenho para criar uma forma vetorial. A saída do sombreador é usada para preencher a forma, da mesma maneira que se pode usar qualquer imagem de bitmap como preenchimento de bitmap com a API de desenho. Para criar um preenchimento de sombreador, no ponto do código em que você deseja começar a desenhar a forma, chame o método beginShaderFill() do objeto Graphics. Passe o objeto Shader como o primeiro argumento do método beginShaderFill() , conforme mostrado nesta listagem:

var canvas:Sprite = new Sprite(); 
canvas.graphics.beginShaderFill(myShader); 
canvas.graphics.drawRect(10, 10, 150, 150); 
canvas.graphics.endFill(); 
// add canvas to the display list to see the result

Quando você usa um sombreador como preenchimento de desenho, deve definir quaisquer valores de imagem de entrada e valores de parâmetro exigidos pelo sombreador.

O exemplo a seguir demonstra o uso de um sombreador como preenchimento de desenho. Neste exemplo, o sombreador cria um gradiente de três pontas. Esse gradiente tem três cores, cada uma na ponta de um triângulo, com uma mesclagem de gradiente entre elas. Além disso, as cores se revezam para criar um efeito animado de cores girando.

Nota: O código deste exemplo foi escrito por Petri Leskinen. Obrigado por compartilhar este exemplo, Petri. Para ver mais exemplos e tutoriais de Petri, acesse http://pixelero.wordpress.com/ .

O código ActionScript está baseado em três métodos:

  • init() : o método init() é chamado quando o aplicativo é carregado. Neste método, o código define os valores iniciais dos objetos Point que representam as pontas do triângulo. O código também cria uma ocorrência de Sprite chamada canvas . Posteriormente, no método updateShaderFill() , o código desenha o resultado do sombreador em canvas uma vez por quadro. Por último, o código carrega o arquivo de código de bytes do sombreador.

  • onLoadComplete() : no método onLoadComplete() , o código cria o objeto Shader chamado shader . Ele também define os valores de parâmetro iniciais. Para terminar, o código adiciona o método updateShaderFill() como um ouvinte do evento enterFrame , o que significa que ele é chamado uma vez por quadro para criar um efeito de animação.

  • updateShaderFill() : o método updateShaderFill() é chamado uma vez por quadro, o que cria o efeito de animação. Neste método, o código calcula e define os valores dos parâmetros do sombreador. O código então chama o método beginShaderFill() para criar um preenchimento de sombreador e chama outros métodos de API de desenho para desenhar o resultado do sombreador em um triângulo.

Veja abaixo o código ActionScript para este exemplo. Use esta classe com a classe de aplicativo principal em um projeto somente ActionScript no Flash Builder ou como a classe do documento para um arquivo FLA no Flash Professional:

package 
{ 
    import flash.display.Shader; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.geom.Point; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
     
    public class ThreePointGradient extends Sprite 
    { 
        private var canvas:Sprite; 
        private var shader:Shader; 
        private var loader:URLLoader; 
         
        private var topMiddle:Point; 
        private var bottomLeft:Point; 
        private var bottomRight:Point; 
         
        private var colorAngle:Number = 0.0; 
        private const d120:Number = 120 / 180 * Math.PI; // 120 degrees in radians 
         
         
        public function ThreePointGradient() 
        { 
            init(); 
        } 
         
        private function init():void 
        { 
            canvas = new Sprite(); 
            addChild(canvas); 
             
            var size:int = 400; 
            topMiddle = new Point(size / 2, 10); 
            bottomLeft = new Point(0, size - 10); 
            bottomRight = new Point(size, size - 10); 
             
            loader = new URLLoader(); 
            loader.dataFormat = URLLoaderDataFormat.BINARY; 
            loader.addEventListener(Event.COMPLETE, onLoadComplete); 
            loader.load(new URLRequest("ThreePointGradient.pbj")); 
        } 
         
        private function onLoadComplete(event:Event):void 
        { 
            shader = new Shader(loader.data); 
             
            shader.data.point1.value = [topMiddle.x, topMiddle.y]; 
            shader.data.point2.value = [bottomLeft.x, bottomLeft.y]; 
            shader.data.point3.value = [bottomRight.x, bottomRight.y]; 
             
            addEventListener(Event.ENTER_FRAME, updateShaderFill); 
        } 
         
        private function updateShaderFill(event:Event):void 
        { 
            colorAngle += .06; 
             
            var c1:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle); 
            var c2:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle + d120); 
            var c3:Number = 1 / 3 + 2 / 3 * Math.cos(colorAngle - d120); 
             
            shader.data.color1.value = [c1, c2, c3, 1.0]; 
            shader.data.color2.value = [c3, c1, c2, 1.0]; 
            shader.data.color3.value = [c2, c3, c1, 1.0]; 
             
            canvas.graphics.clear(); 
            canvas.graphics.beginShaderFill(shader); 
             
            canvas.graphics.moveTo(topMiddle.x, topMiddle.y); 
            canvas.graphics.lineTo(bottomLeft.x, bottomLeft.y); 
            canvas.graphics.lineTo(bottomRight.x, bottomLeft.y); 
             
            canvas.graphics.endFill(); 
        } 
    } 
}

Este é o código-fonte do núcleo de sombreador ThreePointGradient, usado para criar o arquivo de código de bytes do Pixel Bender “ThreePointGradient.pbj”:

<languageVersion : 1.0;> 
kernel ThreePointGradient 
< 
    namespace : "Petri Leskinen::Example"; 
    vendor : "Petri Leskinen"; 
    version : 1; 
    description : "Creates a gradient fill using three specified points and colors."; 
> 
{ 
    parameter float2 point1 // coordinates of the first point 
    < 
        minValue:float2(0, 0); 
        maxValue:float2(4000, 4000); 
        defaultValue:float2(0, 0); 
    >; 
     
    parameter float4 color1 // color at the first point, opaque red by default 
    < 
        defaultValue:float4(1.0, 0.0, 0.0, 1.0); 
    >; 
     
    parameter float2 point2 // coordinates of the second point 
    < 
        minValue:float2(0, 0); 
        maxValue:float2(4000, 4000); 
        defaultValue:float2(0, 500); 
    >; 
     
    parameter float4 color2 // color at the second point, opaque green by default 
    < 
        defaultValue:float4(0.0, 1.0, 0.0, 1.0); 
    >; 
     
    parameter float2 point3 // coordinates of the third point 
    < 
        minValue:float2(0, 0); 
        maxValue:float2(4000, 4000); 
        defaultValue:float2(0, 500); 
    >; 
     
    parameter float4 color3 // color at the third point, opaque blue by default 
    < 
        defaultValue:float4(0.0, 0.0, 1.0, 1.0); 
    >; 
     
    output pixel4 dst; 
     
    void evaluatePixel() 
    { 
        float2 d2 = point2 - point1; 
        float2 d3 = point3 - point1; 
         
        // transformation to a new coordinate system 
        // transforms point 1 to origin, point2 to (1, 0), and point3 to (0, 1) 
        float2x2 mtrx = float2x2(d3.y, -d2.y, -d3.x, d2.x) / (d2.x * d3.y - d3.x * d2.y); 
        float2 pNew = mtrx * (outCoord() - point1); 
         
        // repeat the edge colors on the outside 
        pNew.xy = clamp(pNew.xy, 0.0, 1.0); // set the range to 0.0 ... 1.0 
         
        // interpolating the output color or alpha value 
        dst = mix(mix(color1, color2, pNew.x), color3, pNew.y); 
    } 
}
Nota: Se você usar um preenchimento por sombreamento ao renderizar com a unidade de processamento gráfico (GPU), a área preenchida assumirá a cor ciano.

Para obter mais informações sobre como desenhar formas usando a API de desenho, consulte Uso da API de desenho .