Waarden voor invoer en parameters van arceringen opgeven

Flash Player 10 of hoger, Adobe AIR 1.5 of hoger

Veel Pixel Bender-arceringen worden zodanig gedefinieerd dat er een of meer invoerafbeeldingen worden gebruikt bij het verwerken van de arcering. Het is bijvoorbeeld heel gewoon voor een arcering om een bronafbeelding te accepteren en die afbeelding weer te geven met een bepaald effect. De manier waarop de arcering wordt gebruikt bepaalt of de invoerwaarde automatisch kan worden opgegeven of dat u zelf een waarde moet opgeven. Door veel arceringen worden op een vergelijkbare manier parameters opgegeven die worden gebruikt om de uitvoer van de arcering aan te passen. U moet ook expliciet een waarde instellen voor elke parameter voordat u de arcering gebruikt.

U gebruikt de eigenschap data van het Shader-object om invoer en parameters voor de arcering in te stellen en om na te gaan of een bepaalde arcering invoer of parameters verwacht. De eigenschap data is een ShaderData-instantie.

Invoer en parameters van arceringen identificeren

Bij het identificeren van invoer en parameters van arceringen moet u eerst nagaan of de specifieke arcering die u gebruikt, invoerafbeeldingen of parameters verwacht. Elke Shader-instantie heeft een data -eigenschap met een ShaderData-object. Als in de arcering invoer of parameters worden gedefinieerd, worden ze gebruikt als eigenschappen van dat ShaderData-object. De namen van de eigenschappen komen overeen met de namen die voor de invoer en de parameters in de broncode van de arcering zijn opgegeven. Als in een arcering bijvoorbeeld een invoer met de naam src wordt gedefinieerd, bevat het ShaderData-object een eigenschap met de naam src die staat voor de desbetreffende invoer. Elke eigenschap die een invoer vertegenwoordigt, is een ShaderInput-instantie en elke eigenschap die een parameter vertegenwoordigt is een ShaderParameter-instantie.

In het gunstigste geval biedt de auteur van de arcering documentatie voor de arcering, waarin de waarden voor invoerafbeeldingen en parameters worden aangegeven die door de de arcering worden verwacht, waar deze waarden voor staan, wat de bijbehorende waarden zijn, enzovoort.

Als de arcering echter niet wordt gedocumenteerd (en u beschikt niet over de broncode van de arcering), kunt u de arceringsgegevens inspecteren om de invoerwaarden en parameters te identificeren. De eigenschappen die de invoerwaarden en parameters vertegenwoordigen, worden dynamisch toegevoegd aan het ShaderData-object. U kunt daarom een for..in -lus gebruiken om het ShaderData-object te bekijken om na te gaan of in de aan het object gekoppelde arcering invoerwaarden of parameters zijn gedefinieerd. Zoals werd beschreven in Toegang krijgen tot de metagegevens van arceringen wordt elke metagegevenswaarde die voor een arcering is gedefinieerd, ook opgehaald als een dynamische eigenschap die is toegevoegd aan de eigenschap Shader.data . Wanneer u deze techniek gebruikt om invoer en parameters van arceringen te identificeren, moet u het gegevenstype van de dynamische eigenschappen controleren. Als het bij een eigenschap om een ShaderInput-instantie gaat, vertegenwoordigt de eigenschap een invoerwaarde. Als het een ShaderParameter-instantie is, vertegenwoordigt de eigenschap een parameter. In alle andere gevallen is de eigenschap een metagegevenswaarde. In het volgende voorbeeld wordt getoond hoe u een for..in -lus gebruikt om de dynamische eigenschappen van de eigenschap data van een arcering te bekijken. Elke invoerwaarde (ShaderInput-object) wordt toegevoegd aan een Vector-instantie met de naam inputs . Elke parameter (ShaderParameter-object) wordt toegevoegd aan een Vector-instantie met de naam parameters . Eventuele eigenschappen voor metagegevens worden toegevoegd aan een Vector-instantie met de naam metadata . In dit voorbeeld wordt ervan uitgegaan dat er al een Shader-instantie met de naam myShader is gemaakt:

var shaderData:ShaderData = myShader.data; 
var inputs:Vector.<ShaderInput> = new Vector.<ShaderInput>(); 
var parameters:Vector.<ShaderParameter> = new Vector.<ShaderParameter>(); 
var metadata:Vector.<String> = new Vector.<String>(); 
 
for (var prop:String in shaderData) 
{ 
    if (shaderData[prop] is ShaderInput) 
    { 
        inputs[inputs.length] = shaderData[prop]; 
    } 
    else if (shaderData[prop] is ShaderParameter) 
    { 
        parameters[parameters.length] = shaderData[prop]; 
    } 
    else 
    { 
        metadata[metadata.length] = shaderData[prop]; 
    } 
} 
 
// do something with the inputs or properties

Invoerwaarden voor arceringen opgeven

Veel arceringen verwachten een of meer invoerafbeeldingen die worden gebruikt bij het verwerken van de arcering. In veel gevallen wordt een invoerwaarde echter automatisch opgegeven wanneer het Shader-object wordt gebruikt. Stel dat een arcering één invoerwaarde nodig heeft en dat de arcering als filter wordt gebruikt. Wanneer het filter op een weergaveobject of BitmapData-object wordt toegepast, wordt dat object automatisch als invoerwaarde ingesteld. In dat geval stelt u niet expliciet een invoerwaarde in.

In sommige gevallen moet u echter wel specifiek een invoerwaarde instellen, met name als in een arcering meerdere invoerwaarden zijn gedefinieerd. Elke invoerwaarde die in een arcering is gedefinieerd, wordt in ActionScript vertegenwoordigd door een ShaderInput-object. Het ShaderInput-object is een eigenschap van de ShaderData-instantie in de eigenschap data van het Shader-object, zoals wordt beschreven in Invoer en parameters van arceringen identificeren . Stel dat in een arcering een invoerwaarde met de naam src wordt gedefinieerd en dat die arcering is gekoppeld aan een Shader-object met de naam myShader . In dat geval gebruikt u de volgende id om toegang te krijgen tot het ShaderInput-object dat overeenkomt met de invoerwaarde src :

myShader.data.src

Elk ShaderInput-object heeft een eigenschap input waarmee de waarde voor de invoer wordt ingesteld. U stelt de eigenschap input in op een BitmapData-instantie om afbeeldingsgegevens op te geven. U kunt de eigenschap input ook instellen op een BitmapData of Vector.<Number>-instantie om binaire gegevens of getalsgegevens op te geven. Zie voor meer gegevens en beperkingen over het gebruik van een BitmapData of Vector.<Number>-instantie als invoergegeven de ShaderInput.input -vermelding in de Naslaggids voor ActionScript 3.0 voor het Adobe Flash-platform .

Naast de eigenschap input heeft een ShaderInput-object eigenschappen waarmee het type afbeelding kan worden bepaald dat door de invoer wordt verwacht. Hierbij gaat het onder andere om de eigenschappen width , height en channels . Elk ShaderInput-object heeft ook een eigenschap index , een handige eigenschap om te bepalen of een expliciete waarde voor de invoer moet worden gegeven. Als een arcering meer invoerwaarden verwacht dan het automatisch ingestelde aantal, kunt u de waarden van die invoer instellen. Zie Een arcering gebruiken voor informatie over de verschillende manieren waarop u arceringen kunt gebruiken en om na te gaan of invoerwaarden automatisch worden ingesteld.

Parameterwaarden voor arceringen opgeven

Bij sommige arceringen worden parameterwaarden gedefinieerd waarmee het gewenste resultaat wordt bereikt. Zo kunt u bij een arcering waarmee de helderheid van een afbeelding wordt gewijzigd, bijvoorbeeld een parameter voor helderheid opgeven die aangeeft in hoeverre de helderheid wordt beïnvloed door de bewerking. Een enkele parameter die in een arcering wordt gedefinieerd, kan een enkele of meerdere waarden verwachten, afhankelijk van de parameterdefinitie in de arcering. Elke parameter die in een arcering is gedefinieerd, wordt in ActionScript vertegenwoordigd door een ShaderParameter-object. Het ShaderParameter-object is een eigenschap van de ShaderData-instantie in de eigenschap data van het Shader-object, zoals wordt beschreven in Invoer en parameters van arceringen identificeren . Stel dat in een arcering bijvoorbeeld de parameter brightness wordt gedefinieerd en dat die arcering wordt vertegenwoordigd door een Shader-object met de naam myShader . In dat geval gebruikt u de volgende id om toegang te krijgen tot het ShaderParameter-object dat overeenkomt met de parameter brightness :

myShader.data.brightness

Als u een waarde (of waarden) wilt opgeven voor de parameter, maakt u een ActionScript-array die de waarde of waarden bevat en wijst u deze array toe aan de eigenschap value van het ShaderParameter-object. De eigenschap value is gedefinieerd als een Array-instantie omdat één arceringsparameter mogelijk meerdere waarden vereist. Zelfs als de arceringsparameter slechts één waarde verwacht, moet u de waarde in een Array-object opnemen om de waarde aan de eigenschap ShaderParameter.value toe te kunnen wijzen. In de volgende code wordt getoond hoe een enkele waarde wordt ingesteld als de eigenschap value :

myShader.data.brightness.value = [75];

Als in de broncode van de Pixel Bender voor de arcering een standaardwaarde voor de parameter is gedefinieerd, wordt er een array met de standaardwaarde of -waarden gemaakt en toegewezen aan de eigenschap value van het ShaderParameter-object wanneer het Shader-object wordt gemaakt. Als er eenmaal een array aan de eigenschap value is toegewezen (ook als het de standaardarray is), kan de parameterwaarde worden gewijzigd door de waarde van het array-element te wijzigen. U hoeft geen nieuwe array te maken en deze toe te wijzen aan de eigenschap value .

In het volgende voorbeeld ziet u hoe u de parameterwaarde van een arcering in ActionScript instelt. In dit voorbeeld wordt een parameter met de naam color gedefinieerd. De parameter color wordt gedeclareerd als een float4 -variabele in de broncode van Pixel Bender, wat inhoudt dat het een array van vier getallen met drijvende komma is. In het voorbeeld wordt de waarde van de parameter color voortdurend gewijzigd en telkens wanneer de parameterwaarde wordt gewijzigd, wordt de arcering gebruikt om een gekleurde rechthoek op het scherm te tekenen. Het resultaat is een bewegende kleurverandering.

Opmerking: De code voor dit voorbeeld is geschreven door Ryan Taylor. Onze dank gaat uit naar Ryan, die dit voorbeeld met ons deelt. U kunt de portfolio van Ryan bekijken en zijn codes lezen op www.boostworthy.com/ .

Het draait bij de ActionScript-code om drie methoden:

  • init() : in de methode init() laadt de code het bestand met Pixel Bender-bytecode dat de arcering bevat. Wanneer het bestand is geladen, wordt de methode onLoadComplete() aangeroepen.

  • onLoadComplete() : in de methode onLoadComplete() maakt de code het Shader-object shader . De code maakt ook de nieuwe Sprite-instantie texture . In de methode renderShader() tekent de code het resultaat van de arcering één keer per frame in texture .

  • onEnterFrame() : De methode onEnterFrame() wordt één keer per frame aangeroepen, waarbij het animatie-effect wordt gemaakt. In deze methode wordt de waarde van de arceringsparameter op de nieuwe kleur ingesteld, waarna de methode renderShader() wordt aangeroepen om het arceringsresultaat als een rechthoek te tekenen.

  • renderShader() : in de methode renderShader() roept de code de methode Graphics.beginShaderFill() aan om een vulling met arcering op te geven. Vervolgens wordt een rechthoek getekend waarvan de vulling wordt gedefinieerd door de arceringsuitvoer (de gegenereerde kleur). Zie Een arcering gebruiken als een vulling bij het tekenen voor meer informatie over het gebruik van een arcering op deze manier.

Hier volgt de ActionScript-code voor dit voorbeeld. Gebruik deze klasse als de hoofdtoepassingsklasse voor een alleen-ActionScript-project in Flash Builder of als de documentklasse voor het FLA-bestand 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(); 
        } 
    } 
}

Hier volgt de broncode voor de ColorFilter-arceringskernel die wordt gebruikt om het Pixel Bender-bytecodebestand ColorFilter.pbj te maken:

<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; 
    } 
}

Als u een arcering gebruikt waarvan de parameters moeten worden gedocumenteerd, kunt u erachter komen hoeveel elementen van welk type in de array moeten worden opgenomen door de eigenschap type van het ShaderParameter-object te controleren. De eigenschap type geeft het gegevenstype van de parameter aan, zoals in de arcering zelf is gedefinieerd. Zie de eigenschappenlijst ShaderParameter.value in de Naslaggids voor ActionScript® 3.0 voor Adobe® Flash® Professional CS5 voor een lijst van het aantal en type elementen die door elk parametertype worden verwacht.

Elk ShaderParameter-object heeft ook een eigenschap index die aangeeft waar de parameter past in de volgorde van arceringsparameters. Naast deze eigenschappen kan een ShaderParameter-object extra eigenschappen hebben met metagegevenswaarden die door de auteur van de arcering worden verstrekt. De auteur kan bijvoorbeeld waarden voor metagegevens opgeven, zoals minimum-, maximum- en standaardwaarden voor een parameter. Alle metagegevenswaarden die de auteur opgeeft, worden als dynamische eigenschappen toegevoegd aan het ShaderParameter-object. Als u de eigenschappen wilt onderzoeken, gebruikt u een for..in -lus om de dynamische eigenschappen van het ShaderParameter-object te doorlopen. In het volgende voorbeeld wordt getoond hoe u een for..in -lus gebruikt om de metagegevens van een ShaderParameter-object te identificeren. Elke metagegevenswaarde wordt toegevoegd aan een Vector-instantie met de naam metadata . In dit voorbeeld wordt aangenomen dat er al een Shader-instantie met de naam myShader is gemaakt en dat deze instantie een parameter heeft met de naam 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