Algunos sombreados definen valores de parámetro que el sombreado utiliza al crear su resultado. Por ejemplo, un sombreado que modifica el brillo de una imagen podría especificar un parámetro de brillo que determine el grado en que la operación afecta el brillo. Un solo parámetro definido en un sombreado puede esperar uno o varios valores, en función de la definición de parámetro en el sombreado. Cada parámetro que se define en un sombreado está representado en ActionScript por un objeto ShaderParameter. El objeto ShaderParameter es una propiedad de la instancia de ShaderData de la propiedad data del objeto Shader, como se describe en
Identificación de entradas y parámetros de sombreado
. Por ejemplo, si un sombreado define un parámetro denominado
brightness
, y dicho sombreado está representado por un objeto Shader denominado
myShader
. En este caso se accede al objeto ShaderParameter correspondiente al parámetro
brightness
a través del identificador siguiente:
myShader.data.brightness
Para establecer un valor (o varios valores) para el parámetro, cree un conjunto ActionScript que contenga el valor o los valores y asígnela a la propiedad
value
del objeto ShaderParameter. La propiedad
value
se define como una instancia de Array porque es posible que un solo parámetro de sombreado requiera varios valores. Incluso si el parámetro de sombreado espera únicamente un solo valor, este valor se debe incluir en un objeto Array para asignarlo a la propiedad
ShaderParameter.value
. El listado siguiente muestra cómo establecer un solo valor con la propiedad
value
:
myShader.data.brightness.value = [75];
Si el código fuente de Pixel Bender del sombreado define un valor predeterminado para el parámetro, se creará un conjunto que contendrá el valor o los valores predeterminados y se asignará a la propiedad
value
del ShaderParameter al crear el objeto Shader. Una vez que se ha asignado un conjunto a la propiedad
value
(incluso si se trata del conjunto predeterminado), se podrá modificar el valor de parámetro cambiando el valor del elemento de conjunto. No es necesario crear un conjunto nuevo y asignarlo a la propiedad
value
.
En el ejemplo siguiente se muestra cómo establecer un valor de parámetro de sombreado en ActionScript. En este ejemplo el sombrado define el parámetro
color
. El parámetro
color
se declara como una variable
float4
en el código fuente de Pixel Bender, por lo que se trata de un conjunto de cuatro números de coma flotante. En el ejemplo, el valor del parámetro
color
cambia continuamente, y cada vez que cambia el sombreado se utiliza para dibujar un rectángulo de color en la pantalla. El resultado es un cambio de color animado.
Nota:
el código de este ejemplo fue escrito por Ryan Taylor. Gracias Ryan por compartir este ejemplo. Para obtener información sobre el trabajo de Ryan, consulte
www.boostworthy.com/
.
El código ActionScript se centra en tres métodos:
-
init()
: en el método
init()
el código carga el archivo de código de bytes de Pixel Bender que contiene el sombreado. Cuando se carga el archivo, se llama al método
onLoadComplete()
.
-
onLoadComplete()
: en el método
onLoadComplete()
el código crea el objeto Shader denominado
shader
. También se crea una instancia de Sprite denominada
texture
. En el método
renderShader()
, el código dibuja el resultado del sombreado en
texture
una sola vez por fotograma.
-
onEnterFrame()
: el método
onEnterFrame()
se llama una vez en cada fotograma, lo que crea el efecto de animación. En este método, el código establece el valor del parámetro del sombreado en el color nuevo y, a continuación, llama al método
renderShader()
para dibujar el resultado del sombreado como un rectángulo.
-
renderShader()
: en el método
renderShader()
, el código llama al método
Graphics.beginShaderFill()
para especificar un relleno de sombreado. A continuación, dibuja un rectángulo cuyo relleno viene definido por la salida del sombreado (el color generado). Para obtener más información sobre la utilización de un sombreado de este modo, consulte
Uso de un sombreado como relleno de dibujo
.
Este es el código de ActionScript de este ejemplo. Utilice esta clase como clase principal de aplicación para un proyecto solo ActionScript en Flex, o bien, como la clase de documento para el archivo FLA en 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();
}
}
}
A continuación se incluye el código fuente del núcleo del sombreado ColorFilter, que se utiliza para crear el archivo de código de bytes “ColorFilter.pbj” de 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;
}
}
Si utiliza un sombreado cuyos parámetros no están documentados, podrá determinar cuántos elementos y de qué tipo se deben incluir en el conjunto si comprueba la propiedad
type
del objeto ShaderParameter. La propiedad
type
indica el tipo de datos del parámetro como se define en el propio sombreado. Para obtener una lista del número y tipo de elementos que espera cada tipo de parámetro, consulte el listado de la propiedad
ShaderParameter.value
en la referencia del lenguaje.
Cada objeto ShaderParameter también tiene una propiedad
index
que indica la ubicación adecuada del parámetro en el orden de los parámetros del sombreado. Además de estas propiedades, los objetos ShaderParameter pueden presentar propiedades adicionales que contienen valores de metadatos proporcionados por el autor del sombreado. Por ejemplo, el autor puede especificar los valores de metadatos mínimo, máximo y predeterminado para un parámetro determinado. Los valores de metadatos que el autor especifica se añaden al objeto ShaderParameter como propiedades dinámicas. Para examinar estas propiedades, utilice el bucle
for..in
para recorrer las propiedades dinámicas del objeto ShaderParameter e identificar sus metadatos. El ejemplo siguiente muestra cómo utilizar un bucle
for..in
para identificar los metadatos de un objeto ShaderParameter. Cada valor de metadatos se añade a una instancia de Vector denominada
metadata
. Tenga en cuenta que este ejemplo asume que las instancias de Shader
myShader
ya están creadas, y que tienen un parámetro
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