Einige Shader definieren Parameterwerte, die der Shader zum Erstellen der Ergebnisse nutzt. Ein Shader, der die Helligkeit eines Bilds ändert, kann beispielsweise einen Parameter für die Helligkeit angeben, der festlegt, inwieweit die Helligkeit durch den Vorgang angepasst wird. Für einen einzelnen, in einem Shader definierten Parameter können ein oder mehrere Werte vorausgesetzt werden, je nach Parameterdefinition im Shader. Jeder Parameter, der in einem Shader definiert ist, wird in ActionScript durch ein ShaderParameter-Objekt dargestellt. Das ShaderParameter-Objekt ist eine Eigenschaft der ShaderData-Instanz in der data-Eigenschaft des Shader-Objekts, wie unter
Identifizieren von Shader-Eingaben und -Parametern
beschrieben. Beispiel: Ein Shader definiert einen Parameter mit dem Namen
brightness
und dieser Shader wird durch ein Shader-Objekt mit dem Namen
myShader
dargestellt. In diesem Fall greifen Sie auf das ShaderParameter-Objekt für den Parameter
brightness
unter Verwendung des folgenden Bezeichners zu:
myShader.data.brightness
Um einen oder mehrere Werte für den Parameter anzugeben, erstellen Sie ein ActionScript-Array mit den Werten und weisen dieses Array der
value
-Eigenschaft des ShaderParameter-Objekts zu. Die
value
-Eigenschaft ist als Array-Instanz definiert, da ein einzelner Shader-Parameter mehrere Werte voraussetzen kann. Selbst wenn der Shader-Parameter nur einen Wert erfordert, müssen Sie den Wert in das Array-Objekt einschließen, um ihn der
ShaderParameter.value
-Eigenschaft zuzuweisen. Im Folgenden wird die Einstellung eines einzelnen Werts als
value
-Eigenschaft erläutert.
myShader.data.brightness.value = [75];
Wenn der Pixel Bender-Quellcode des Shaders einen Standardwert für den Parameter definiert, wird beim Erstellen des Shader-Objekts ein Array mit den Standardwerten erstellt und der
value
-Eigenschaft des ShaderParameter-Objekts zugewiesen. Nachdem der
value
-Eigenschaft ein Array zugewiesen wurde (auch wenn es das Standard-Array ist), können Sie den Parameterwert ändern, indem Sie den Wert des Array-Elements bearbeiten. Sie müssen kein neues Array erstellen und der
value
-Eigenschaft zuweisen.
Das folgende Beispiel veranschaulicht, wie Sie den Parameterwert eines Shaders in ActionScript festlegen. In diesem Beispiel definiert der Shader einen Parameter mit dem Namen
color
. Der
color
-Parameter ist als eine
float4
-Variable im Pixel Bender-Quellcode deklariert, d. h. es handelt sich um ein Array mit vier Gleitkommazahlen. In diesem Beispiel wird der Wert des
color
-Parameters kontinuierlich geändert. Bei jeder Änderung wird der Shader verwendet, um ein farbiges Rechteck auf dem Bildschirm zu zeichnen. Das Ergebnis ist eine animierte Farbänderung.
Hinweis:
Der Code für dieses Beispiel wurde von Ryan Taylor geschrieben. Vielen Dank an Ryan für die Bereitstellung dieses Beispiels. Unter
www.boostworthy.com/
können Sie Ryans Mappe einsehen und seine Texte lesen.
Der ActionScript-Code basiert primär auf drei Methoden:
-
init()
: In der
init()
-Methode lädt der Code die Pixel Bender-Bytecodedatei, die den Shader enthält. Beim Laden der Datei wird die
onLoadComplete()
-Methode aufgerufen.
-
onLoadComplete()
: In der
onLoadComplete()
-Methode erstellt der Code das Shader-Objekt mit dem Namen
shader
. Er erstellt außerdem eine Sprite-Instanz mit dem Namen
texture
. In der
renderShader()
-Methode zeichnet der Code das Shader-Ergebnis pro Bild einmal in
texture
.
-
onEnterFrame()
: Die
onEnterFrame()
-Methode wird einmal pro Bild aufgerufen und erzeugt den Animationseffekt. In dieser Methode legt der Code für den Shader-Parameterwert die neue Farbe fest. Anschließend wird die
renderShader()
-Methode aufgerufen, um das Ergebnis des Shaders in Form eines Rechtecks zu zeichnen.
-
renderShader()
: In der
renderShader()
-Methode ruft der Code die
Graphics.beginShaderFill()
-Methode auf, um eine Füllung für den Shader anzugeben. Anschließend wird ein Rechteck gezeichnet, dessen Füllung durch die Shader-Ausgabe (die generierte Farbe) definiert wird. Weitere Informationen zu dieser Verwendung des Shaders finden Sie unter
Verwenden eines Shaders als Füllmuster für Zeichnungen
.
Im Folgenden wird der ActionScript-Code für dieses Beispiel angezeigt. Verwenden Sie diese Klasse als Hauptanwendungsklasse für ausschließlich in ActionScript erstellte Projekte in Flash Builder oder als Dokumentklasse für die FLA-Datei 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();
}
}
}
Im Folgenden ist der Quellcode für den Kernel des ColorFilter-Shaders dargestellt, der zum Erstellen der Pixel Bender-Bytecodedatei „ColorFilter.pbj“ verwendet wurde:
<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;
}
}
Wenn Sie einen Shader verwenden, dessen Parameter nicht dokumentiert sind, können Sie die Art und Anzahl der Elemente, die in das Array eingeschlossen werden müssen, durch Überprüfen der
type
-Eigenschaft des ShaderParameter-Objekts ermitteln. Die
type
-Eigenschaft gibt den Datentyp des Parameters an, der im Shader selbst definiert ist. Eine Liste mit Informationen zu Art und Anzahl der Elemente, die von jedem Parametertyp vorausgesetzt werden, finden Sie im ActionScript 3.0-Referenzhandbuch unter
ShaderParameter.value
.
Jedes ShaderParameter-Objekt verfügt zudem über eine
index
-Eigenschaft, die die Position des Parameters in der Reihenfolge der Shader-Parameter angibt. Neben diesen Eigenschaften kann ein ShaderParameter-Objekt weitere Eigenschaften aufweisen, die vom Ersteller des Shaders bereitgestellte Metadatenwerte enthalten. Der Ersteller kann beispielsweise Metadatenwerte wie Minimum und Maximum sowie Standardwerte für einen Parameter festlegen. Alle vom Ersteller angegebenen Metadatenwerte werden dem ShaderParameter-Objekt als dynamische Eigenschaften hinzugefügt. Verwenden Sie zum Analysieren dieser Eigenschaften eine
for..in
-Schleife, um die dynamischen Eigenschaften des ShaderParameter-Objekts anzuzeigen und die zugehörigen Metadaten zu identifizieren. Das folgende Beispiel veranschaulicht, wie Sie mit der
for..in
-Schleife die Metadaten eines ShaderParameter-Objekts identifizieren. Jeder Metadatenwert wird einer Vector-Instanz mit dem Namen
metadata
hinzugefügt. Beachten Sie, dass für dieses Beispiel eine Shader-Instanz mit dem Namen
myShader
bereits erstellt sein muss und dass diese einen Parameter mit dem Namen
brightness
aufweisen muss:
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