Alcuni shader definiscono i valori dei parametri che lo shader usa per creare i risultati. Ad esempio, uno shader che altera la luminosità di un'immagine può specificare un parametro di luminosità che determina a che livello l'operazione deve influenzare la luminosità. Un singolo parametro definito in uno shader può richiedere uno o più valori, a seconda della definizione del parametro fornita nello shader. Ogni parametro che viene definito in uno shader è rappresentato in ActionScript da un oggetto ShaderParameter. L'oggetto ShaderParameter è una proprietà dell'istanza ShaderData all'interno della proprietà data dell'oggetto Shader, come spiegato in
Identificazione di input e parametri degli shader
. Ad esempio, supponete che uno shader definisca un parametro chiamato
brightness
e che lo shader sia rappresentato da un oggetto Shader chiamato
myShader
. In questo caso per accedere all'oggetto ShaderParameter corrispondente al parametro
brightness
, è necessario usare l'identificatore seguente:
myShader.data.brightness
Per specificare uno o più valori per il parametro, dovete creare un array di ActionScript contenente i valori appropriati e assegnarli alla proprietà
value
. La proprietà
value
è definita come un'istanza Array, in quanto è possibile che un singolo parametro dello shader richieda più valori. Anche se il parametro dello shader richiede un singolo valore, dovete inserirlo in un oggetto Array per assegnarlo alla proprietà
ShaderParameter.value
. L'elenco seguente indica come impostare un singolo valore come proprietà
value
:
myShader.data.brightness.value = [75];
Se il codice sorgente di Pixel Bender per lo shader definisce un valore predefinito per il parametro, un array contenente il valore o i valori predefiniti viene creato e assegnato alla proprietà
value
dell'oggetto ShaderParameter quando si crea un oggetto Shader. Dopo che l'array viene assegnato alla proprietà
value
(specificando anche se si tratta dell'array predefinito), il valore del parametro può essere modificato cambiando il valore dell'elemento dell'array. Non è necessario creare un nuovo array e assegnarlo alla proprietà
value
.
L'esempio seguente dimostra come impostare il valore di un parametro dello shader in ActionScript. In questo esempio lo shader definisce un parametro chiamato
color
. Il parametro
color
viene dichiarato come variabile
float4
nel codice sorgente di Pixel Bender; ciò significa che si tratta di un array di quattro numeri a virgola mobile. Nell'esempio, il valore del parametro
color
viene cambiato continuamente e ogni volta che cambia lo shader viene usato per disegnare un rettangolo colorato sullo schermo. Il risultato è un cambio di colore animato.
Nota:
il codice di questo esempio è stato scritto da Ryan Taylor, che ringraziamo per avere condiviso questo esempio. Potete consultare il lavoro di Ryan sul sito all'indirizzo
www.boostworthy.com/
.
Il codice ActionScript è incentrato su tre metodi:
-
init()
: nel metodo
init()
il codice carica il codice byte Pixel Bender contenente lo shader. Quando il file viene caricato, viene chiamato il metodo
onLoadComplete()
.
-
onLoadComplete()
: nel metodo
onLoadComplete()
il codice crea l'oggetto Shader denominato
shader
e un'istanza di Sprite denominata
texture
. Nel metodo
renderShader()
il codice disegna il risultato dello shader in
texture
una volta per fotogramma.
-
onEnterFrame()
: il metodo
onEnterFrame()
viene chiamato una volta per ogni frame per realizzare l'effetto di animazione. In questo metodo il codice imposta il valore del parametro dello shader su un nuovo colore, quindi chiama il metodo
renderShader()
per disegnare il risultato dello shader sotto forma di un rettangolo.
-
renderShader()
: nel metodo
renderShader()
il codice chiama il metodo
Graphics.beginShaderFill()
per specificare un riempimento per lo shader, quindi disegna un rettangolo il cui riempimento è definito dall'output dello shader (il colore generato). Per ulteriori informazioni su questo tipo di uso degli shader, vedete
Uso di uno shader come riempimento
.
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.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
public class ColorFilterExample extends Sprite
{
private const DELTA_OFFSET:Number = Math.PI * 0.5;
private var loader:URLLoader;
private var shader:Shader;
private var texture:Sprite;
private var delta:Number = 0;
public function ColorFilterExample()
{
init();
}
private function init():void
{
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("ColorFilter.pbj"));
}
private function onLoadComplete(event:Event):void
{
shader = new Shader(loader.data);
texture = new Sprite();
addChild(texture);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
shader.data.color.value[0] = 0.5 + Math.cos(delta - DELTA_OFFSET) * 0.5;
shader.data.color.value[1] = 0.5 + Math.cos(delta) * 0.5;
shader.data.color.value[2] = 0.5 + Math.cos(delta + DELTA_OFFSET) * 0.5;
// The alpha channel value (index 3) is set to 1 by the kernel's default
// value. This value doesn't need to change.
delta += 0.1;
renderShader();
}
private function renderShader():void
{
texture:graphics.clear();
texture.graphics.beginShaderFill(shader);
texture.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
texture.graphics.endFill();
}
}
}
Viene di seguito riportato il codice sorgente per il kernel dello shader ColorFilter, usato per creare il file del codice byte “ColorFilter.pbj” Pixel Bender:
<languageVersion : 1.0;>
kernel ColorFilter
<
namespace : "boostworthy::Example";
vendor : "Ryan Taylor";
version : 1;
description : "Creates an image where every pixel has the specified color value.";
>
{
output pixel4 result;
parameter float4 color
<
minValue:float4(0, 0, 0, 0);
maxValue:float4(1, 1, 1, 1);
defaultValue:float4(0, 0, 0, 1);
>;
void evaluatePixel()
{
result = color;
}
}
Se usate uno shader i cui parametri non sono documentati, potete scoprire quanti elementi di quale tipo devono essere inclusi nell'array controllando la proprietà
type
dell'oggetto ShaderParameter. La proprietà
type
indica il tipo di dati del parametro così come è definito nello shader. Per un elenco che riporta numeri e tipi degli elementi richiesti da ogni tipo di parametro, vedete la voce della proprietà
ShaderParameter.value
nella Guida di riferimento di ActionScript 3.0.
Ciascun oggetto ShaderParameter prevede inoltre una proprietà
index
che indica la posizione in cui si trova il parametro nell'ordine dei parametri dello shader. Oltre a queste proprietà, un oggetto ShaderParameter può avere altre proprietà contenenti i valori dei metadati forniti dall'autore dello shader. Ad esempio, l'autore può specificare valori dei metadati quali i valori minimo, massimo e predefinito per un parametro. Tutti i valori dei metadati specificati da un autore vengono aggiunti all'oggetto ShaderParameter come proprietà dinamiche. Per esaminare queste proprietà, utilizzate un ciclo
for..in
per scorrere le proprietà dinamiche dell'oggetto ShaderParameter e identificarne i metadati. L'esempio seguente illustra come utilizzare un ciclo
for..in
per identificare i metadati di un oggetto ShaderParameter. Ogni valore dei metadati viene aggiunto a un'istanza Vector il cui nome è
metadata
. Si noti che questo esempio presuppone che sia già stata creata l'istanza Shader
myShader
contenente il parametro
brightness
:
var brightness:ShaderParameter = myShader.data.brightness;
var metadata:Vector.<String> = new Vector.<String>();
for (var prop:String in brightness)
{
if (brightness[prop] is String)
{
metadata[metadata.length] = brightness[prop];
}
}
// do something with the metadata