Arceringen als overvloeimodus gebruiken

Flash Player 10 of hoger, Adobe AIR 1.5 of hoger

Het gebruik van een arcering als overvloeimodus is vergelijkbaar met andere overvloeimodi. De arcering definieert de weergave die het resultaat is van twee weergaveobjecten die visueel in elkaar overvloeien. Als u een arcering als overvloeimodus wilt gebruiken, wijst u het Shader-object toe aan de eigenschap blendShader van het weergaveobject op de voorgrond. Door een andere waarde dan null toe te wijzen aan de eigenschap blendShader , wordt de eigenschap blendMode van het weergaveobject automatisch ingesteld op BlendMode.SHADER . In het volgende codevoorbeeld ziet u hoe u een arcering gebruikt als overvloeimodus. In dit voorbeeld wordt verondersteld dat er een weergaveobject met de naam foreground is in hetzelfde bovenliggende item in de weergavelijst als andere weergave-inhoud, waarbij foreground de andere inhoud overlapt:

foreground.blendShader = myShader;

Wanneer u een arcering als overvloeimodus gebruikt, moet de arcering zijn gedefinieerd met ten minste twee invoeren. Zoals u in het voorbeeld ziet, stelt u de invoerwaarden niet in de code in. In plaats daarvan worden de twee overgevloeide afbeeldingen automatisch gebruikt als invoer voor de arcering. De voorgrondafbeelding wordt ingesteld als de tweede afbeelding. Dit is het weergaveobject waarop de overvloeimodus wordt toegepast. Er wordt een achtergrondafbeelding gemaakt door de combinatie te nemen van alle pixels achter het kader van de voorgrondafbeelding. De achtergrondafbeelding wordt ingesteld als de eerste invoerafbeelding. Als u een arcering gebruikt die meer dan twee invoeren verwacht, geeft u voor elke invoer na de eerste twee een waarde op.

In het volgende codevoorbeeld ziet u hoe u een arcering als overvloeimodus gebruikt. In dit voorbeeld wordt een lichtermakende overvloeimodus op basis van lichtsterkte gebruikt. Het resultaat van de overvloeiing is dat de lichtste pixelwaarde van de overgevloeide objecten, de pixel is die wordt weergegeven.

Opmerking: De code voor dit voorbeeld is geschreven door Mario Klingemann. Onze dank gaat uit naar Mario, die dit voorbeeld met ons deelt. U kunt meer werk van Ryan bekijken en zijn codes lezen op www.quasimondo.com/ .

De belangrijke ActionScript-code heeft deze twee methoden:

  • init() : de methode init() wordt aangeroepen wanneer de toepassing wordt geladen. In deze methode laadt de code het bytecodebestand voor de arcering.

  • onLoadComplete() : in de methode onLoadComplete() maakt de code het Shader-object shader . Vervolgens worden drie objecten getekend. Het eerste, backdrop , is een donkergrijze achtergrond achter de overgevloeide objecten. Het tweede, backgroundShape , is een ellips met een groen kleurverloop. Het derde, foregroundShape , is een ellips met een oranje kleurverloop.

    De ellips foregroundShape is het voorgrondobject van de overvloeiing. De achtergrondafbeelding van de overvloeiing wordt gevormd door het deel van backdrop en het deel van backgroundShape die worden overlapt door het kader van het foregroundShape -object. Het foregroundShape -object is het object helemaal vooraan in de weergavelijst. Het overlapt backgroundShape gedeeltelijk en overlapt backdrop volledig. Vanwege deze overlapping zou, als er geen overvloeimodus werd toegepast, de oranje ellips ( foregroundShape ) volledig zichtbaar zijn en zou een gedeelte van de groene ellips ( backgroundShape ) er door worden verborgen:

    Maar als de overvloeimodus wordt toegepast, schijnt het lichtere deel van de groene ellips als het ware door de oranje ellips omdat dit deel lichter is dan het deel van foregroundShape dat het overlapt:

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.BlendMode; 
    import flash.display.GradientType; 
    import flash.display.Graphics; 
    import flash.display.Shader; 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.geom.Matrix; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
     
    public class LumaLighten extends Sprite 
    { 
        private var shader:Shader; 
        private var loader:URLLoader; 
         
        public function LumaLighten() 
        { 
            init(); 
        } 
         
        private function init():void 
        { 
            loader = new URLLoader(); 
            loader.dataFormat = URLLoaderDataFormat.BINARY; 
            loader.addEventListener(Event.COMPLETE, onLoadComplete); 
            loader.load(new URLRequest("LumaLighten.pbj")); 
        } 
         
         
        private function onLoadComplete(event:Event):void 
        { 
            shader = new Shader(loader.data); 
             
            var backdrop:Shape = new Shape(); 
            var g0:Graphics = backdrop.graphics; 
            g0.beginFill(0x303030); 
            g0.drawRect(0, 0, 400, 200); 
            g0.endFill(); 
            addChild(backdrop); 
             
            var backgroundShape:Shape = new Shape(); 
            var g1:Graphics = backgroundShape.graphics; 
            var c1:Array = [0x336600, 0x80ff00]; 
            var a1:Array = [255, 255]; 
            var r1:Array = [100, 255]; 
            var m1:Matrix = new Matrix(); 
            m1.createGradientBox(300, 200); 
            g1.beginGradientFill(GradientType.LINEAR, c1, a1, r1, m1); 
            g1.drawEllipse(0, 0, 300, 200); 
            g1.endFill(); 
            addChild(backgroundShape); 
             
            var foregroundShape:Shape = new Shape(); 
            var g2:Graphics = foregroundShape.graphics; 
            var c2:Array = [0xff8000, 0x663300]; 
            var a2:Array = [255, 255]; 
            var r2:Array = [100, 255]; 
            var m2:Matrix = new Matrix(); 
            m2.createGradientBox(300, 200); 
            g2.beginGradientFill(GradientType.LINEAR, c2, a2, r2, m2); 
            g2.drawEllipse(100, 0, 300, 200); 
            g2.endFill(); 
            addChild(foregroundShape); 
             
            foregroundShape.blendShader = shader; 
            foregroundShape.blendMode = BlendMode.SHADER; 
        } 
    } 
}

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

<languageVersion : 1.0;> 
kernel LumaLighten 
< 
    namespace : "com.quasimondo.blendModes"; 
    vendor : "Quasimondo.com"; 
    version : 1; 
    description : "Luminance based lighten blend mode"; 
> 
{ 
    input image4 background; 
    input image4 foreground; 
 
    output pixel4 dst; 
     
    const float3 LUMA = float3(0.212671, 0.715160, 0.072169); 
 
    void evaluatePixel() 
    { 
        float4 a = sampleNearest(foreground, outCoord()); 
        float4 b = sampleNearest(background, outCoord()); 
        float luma_a = a.r * LUMA.r + a.g * LUMA.g + a.b * LUMA.b; 
        float luma_b = b.r * LUMA.r + b.g * LUMA.g + b.b * LUMA.b; 
         
        dst = luma_a > luma_b ? a : b; 
    } 
}

Zie Overvloeimodi toepassen voor meer informatie over het gebruik van overvloeimodi.

Opmerking: Wanneer een Pixel Bender-arceringsprogramma wordt uitgevoerd als arceringsfunctie in Flash Player of AIR, gedragen de arceringsfunctie en de functie outCoord() zich anders dan in andere contexten. Bij een arcering retourneert de samplingfunctie altijd de huidige pixel die door de arceringsfunctie wordt geëvalueerd. Het is bijvoorbeeld niet mogelijk om een verschuiving te gebruiken bij outCoord() om een nabijgelegen pixel te evalueren. Op dezelfde manier geldt dat als u de functie outCoord() buiten een samplingfunctie gebruikt, dat de coördinaten altijd worden geëvalueerd als 0. U kunt bijvoorbeeld niet de positie van een pixel gebruiken om de manier waarop de gearceerde afbeeldingen worden gecombineerd te beïnvloeden.