Quando usate uno shader per creare un riempimento, fate ricorso a metodi di un'API di disegno per creare una forma vettoriale. L'output dello shader viene utilizzato per riempire la forma esattamente come è possibile usare qualsiasi immagine bitmap come riempimento bitmap con l'API di disegno. Per creare un riempimento dello shader, chiamate il metodo
beginShaderFill()
dell'oggetto Graphics nel punto del codice in cui desiderate iniziare a disegnare la forma. Passate l'oggetto Shader come primo argomento al metodo
beginShaderFill()
, come mostrato nel codice seguente:
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 usate uno shader come riempimento, impostate tutti i valori dell'immagine di input e dei parametri richiesti dallo shader.
L'esempio seguente dimostra l'uso di uno shader come riempimento. In questo esempio, lo shader crea un gradiente a tre punti, composto da tre colori, uno a ogni vertice del triangolo, con una sfumatura tra i colori. I colori inoltre ruotano per creare un effetto di animazione di rotazione del colore.
Nota:
il codice di questo esempio è stato scritto da Petri Leskinen, che ringraziamo per avere condiviso questo esempio. Ulteriori esempi ed esercitazioni sviluppati da Petri sono disponibili all'indirizzo
http://pixelero.wordpress.com/
.
Il codice ActionScript è presente in tre metodi:
-
init()
: il metodo
init()
viene chiamato quando viene caricata l'applicazione. In questo metodo il codice imposta i valori iniziali per gli oggetti Point che rappresentano i vertici del triangolo e crea e un'istanza di Sprite denominata
canvas
. In seguito, nel metodo
updateShaderFill()
il codice disegna il risultato dello shader in
canvas
una volta per fotogramma. Infine il codice carica il file di codice byte dello shader.
-
onLoadComplete()
: nel metodo
onLoadComplete()
il codice crea l'oggetto Shader denominato
shader
e imposta i valori iniziali dei parametri. Infine il codice aggiunge il metodo
updateShaderFill()
come listener per l'evento
enterFrame
, che viene quindi chiamato una volta per fotogramma per creare un effetto di animazione.
-
updateShaderFill()
: il metodo
updateShaderFill()
viene chiamato una volta per ogni fotogramma per creare l'effetto di animazione. In questo metodo il codice calcola e imposta i valori dei parametri dello shader, quindi chiama il metodo
beginShaderFill()
per creare un riempimento e chiama altri metodi dell'API di disegno per disegnare il risultato dello shader in un triangolo.
Viene di seguito riportato il codice ActionScript per questo esempio. Utilizzate questa classe come classe di applicazione principale per un progetto costituito solo da ActionScript in Flash Builder o come classe di documento per il file FLA in 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();
}
}
}
Viene di seguito riportato il codice sorgente per il kernel dello shader ThreePointGradient, usato per creare il file del codice byte “ThreePointGradient.pbj” Pixel Bender:
<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 utilizzate un riempimento dello shader durante il rendering nell'unità di elaborazione grafica (GPU), l'area piena verrà colorata ciano.
Per ulteriori informazioni sul disegno di forme mediante l'API di disegno, vedete
Uso dell'API di disegno
.