L'uso di uno shader come metodo di fusione è analogo all'uso di altri metodi di fusione. Lo shader definisce l'aspetto risultante da due oggetti di visualizzazione che vengono fusi visivamente. Per utilizzare uno shader come metodo di fusione, assegnate all'oggetto Shader la proprietà
blendShader
dell'oggetto di visualizzazione in primo piano. L'assegnazione di un valore diverso da
null
alla proprietà
blendShader
imposta automaticamente la proprietà
blendMode
dell'oggetto di visualizzazione su
BlendMode.SHADER
. L'esempio seguente dimostra l'uso di uno shader come metodo di fusione. Tenete presente che in questo esempio si presume che sia disponibile un oggetto di visualizzazione denominato
foreground
contenuto nello stesso oggetto principale nell'elenco di visualizzazione di altro contenuto di visualizzazione, con
foreground
che si sovrappone all'altro contenuto:
foreground.blendShader = myShader;
Quando utilizzate uno shader come metodo di fusione, questo deve essere definito con almeno due input. Come mostra l'esempio, non dovete impostare i valori di input nel codice, perché le due immagini fuse vengono usate automaticamente come input dello shader. L'immagine in primo piano viene impostata come seconda immagine, ovvero l'oggetto di visualizzazione a cui viene applicato il metodo di fusione. Viene creata un'immagine di sfondo utilizzando l'insieme di tutti i pixel dietro il riquadro di delimitazione dell'immagine in primo piano. Questa immagine di sfondo viene impostata come prima immagine di input. Se usate uno shader che prevede più di due input, dovete fornire il valore degli input successivi ai primi due.
L'esempio seguente dimostra l'uso di uno shader come metodo di fusione. Questo esempio utilizza un metodo di fusione basato sulla luminosità. Il risultato della fusione è che il valore del pixel più luminoso di uno degli oggetti fusi diventa il pixel visualizzato.
Nota:
il codice di questo esempio è stato scritto da Mario Klingemann, che ringraziamo per avere condiviso questo esempio. Potete consultare il lavoro di Mario sul sito all'indirizzo
www.quasimondo.com/
.
Il codice ActionScript importante è presente in questi due metodi:
-
init()
: il metodo
init()
viene chiamato quando viene caricata l'applicazione. In questo metodo il codice carica il file di codice byte dello shader.
-
onLoadComplete()
: nel metodo
onLoadComplete()
il codice crea l'oggetto Shader denominato
shader
e quindi disegna tre oggetti. Il primo,
backdrop
, è uno sfondo grigio scuro dietro gli oggetti fusi. Il secondo,
backgroundShape
, è un'ellissi sfumata verde. Il terzo oggetto,
foregroundShape
, è un'ellissi sfumata arancione.
L'ellissi
foregroundShape
è l'oggetto in primo piano della sfumatura. L'immagine di sfondo della sfumatura è formata dalla parte di
backdrop
e la parte di
backgroundShape
che si sovrappongono al riquadro di delimitazione dell'oggetto
foregroundShape
. L'oggetto
foregroundShape
è l'oggetto in primo piano nell'elenco di visualizzazione. Si sovrappone parzialmente con
backgroundShape
e totalmente con
backdrop
. A causa di questa sovrapposizione, se non viene applicato un metodo di fusione, l'ellissi arancione (
foregroundShape
) viene visualizzata completamente e parte dell'ellissi verde
backgroundShape
) viene nascosta da quest'ultima:
Se invece viene applicato un metodo di fusione, la parte più luminosa dell'ellisse verde si intravede, perché è più luminosa della porzione di
foregroundShape
che la copre:
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.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;
}
}
}
Viene di seguito riportato il codice sorgente per il kernel dello shader LumaLighten, usato per creare il file del codice byte “LumaLighten.pbj” Pixel Bender:
<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;
}
}
Per ulteriori informazioni sull'uso dei metodi di fusione, vedete
Applicazione dei metodi di fusione
.
Nota:
quando un programma di shader Pixel Bender viene eseguito come un metodo di fusione in Flash Player o AIR, le funzioni di campionamento e
outCoord()
si comportano in maniera diversa rispetto ad altri contesti. In un metodo di fusione, una funzione di campionamento restituisce sempre il pixel in corso di valutazione. Non potete, ad esempio, aggiungere un offset a
outCoord()
per campionare un pixel vicino. Analogamente, se utilizzate la funzione
outCoord()
al di fuori di una funzione di campionamento, le sue coordinate sono sempre valutate a 0. Non potete, ad esempio, utilizzare la posizione di un pixel per influenzare il modo in cui le immagini fuse sono combinate.