Pixel Bender 2. - filter ve Flashi
November 26th, 2008
V minulém díle (http://tom.krcha.com/pixel-bender-1-uvod/) jsme si představili v kostce jazyk Pixel Bender. Vzhledem k tomu, že je již konečně ke stažení CS4 Trial a všichni si jej můžou vyzkoušet, přešel bych rovnou k věci, a sice aplikaci Pixel Bender filtrů ve Flashi 10.
Aplikace, kterou si dnes vytvoříme je zde.![]()
(Musíte mít nainstalovaný Flash Player 10)
1) Stáhněte si a nainstalujte Flash CS4 z www.adobe.com/cz/downloads/
2) Nachystejte si nějaký Pixel Bender filter (viz. inspirace v minulém díle)
Ideální však bude použít nějaký pokročilejší filtr. Já jsem zvolil twirl.pbk - příklad, který se nainstaluje s Pixel Benderem.
- Otevřete twirl.pbk v Pixel Bender Toolkit
- File -> Export Kernel Filter For Flash Player … uložte soubor *.pbj - pokud nastane problém při exportu*, odstraňte některé nepodporované části nebo použijte můj vyexportovaný twirl.pbj.

* Flash Player Pixel Bender Runtime nepodporuje všechny možnosti jazyka Pixel Bender (např. blok needed) - o těchto možnostech si řekneme v dalším dílech.
3) Spusťte Flash CS4
- Vytvoříme si třídu PixelBenderLoader, která bude načítat filtry za běhu a aplikovat je na jakýkoliv DisplayObject = snad jakákoliv vizuální komponenta, MovieClip, Video, Fotka, Vektor apod.
- PixelBenderLoader je moje třída, kterou můžete používat, nicméně inovaci se meze nekladou a určitě si najdete vlastní cestu pro vaše konkrétní využití.
package { import flash.display.*; import flash.events.*; import flash.filters.*; import flash.net.*; import flash.events.EventDispatcher; public class PixelBenderLoader extends EventDispatcher { private var loader:URLLoader; private var shader:Shader; // ShaderFilter muzeme aplikovat pomoci parametru filters DisplayObjectu private var filter:ShaderFilter; public function PixelBenderLoader():void { } // nacteni filtru public function loadFilter(filterURL:String):void{ loader = new URLLoader(); loader.dataFormat = URLLoaderDataFormat.BINARY; // odchytime jen udalost nacteni, doporucuju vsak odchytit pripadne errory loader.addEventListener(Event.COMPLETE, onComplete); loader.load(new URLRequest(filterURL)); } // aplikuje filter pomoci transformacni objektu public function applyFilter(displayObject:DisplayObject,transformObject:Object){ applyShaderWithTransformObject(shader,transformObject); filter = new ShaderFilter(shader); displayObject.filters = [filter]; } // vrati filter pro pripadnou aplikaci volnejsim zpusobem public function getFilter(transformObject:Object):ShaderFilter{ applyShaderWithTransformObject(shader,transformObject); filter = new ShaderFilter(shader); return filter; } // aplikuje transformacni objekt na shader pomoci cyklu protected function applyShaderWithTransformObject(shader:Shader,transformObject:Object):void{ for(var i:String in transformObject){ shader.data[i].value = [transformObject[i]]; } } // po načtení filteru protected function onComplete(e:Event):void { shader = new Shader(loader.data); dispatchEvent(e); } } }
transformObject:Object - hodnoty parametrů, které filter umožňuje měnit
např. tranformObject = {radius:150};
- Ve Flashi pak použijeme filter tímto způsobem
Načtení filtru:
var pbl:PixelBenderLoader = new PixelBenderLoader(); pbl.addEventListener(Event.COMPLETE,onComplete); pbl.loadFilter("twirl.pbj");
Aplikace filtru - v tomto případě budeme měnit radius:
(deformClip je klasický MovieClip v library, obsahuje fotku a dynamický text)
function applyRadius(radius:Number){ // transformacni objekt, zmenime jen radius var transformObject:Object = new Object(); transformObject.radius = radius; // zmen dynamicky text deformClip.txt.text = radius.toString(); // aplikuj filtr pbl.applyFilter(deformClip,transformObject); }
Změna parametru při pohybu myši:
// zmen radius pri pohybu mysi function mouseMoveChange(event:MouseEvent):void{ applyRadius(Math.abs(event.localX)); }
Odchycení události načtení filtru - v tuto chvíli lze začít filter používat:
function onComplete(e:Event):void{ trace("filter load complete - aplikace"); applyRadius(100); stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveChange); }
Facebook comments:
9 Comments »
RSS feed for comments on this post. / TrackBack URL




Zdravim.
super clanok od ktoreho sa odrazilo vela ludi.
Napada ma ci by sa do triedy nedal importovat uz nacitany filter. a nie ho vzdy nacitat. pricom by bola trieda univerzalna
nieco taketo :
pbl.loadEmbedFilter(”pixelate.pbj”);
ostatne metody zachovali.
alebo to napvno anstavit do tej triedy.
sukusal som to dlho ale bez uspesne
[Embed(source='Test_filter.pbj',mimeType='application/octet-stream')]
private static const WaterKernel: Class;
Comment by TS — March 7, 2009 @ 2:09 am
Diky.
Tu druhou variantu bych musel vyzkouset. V tuto chvili si nejsem jisty zdali to tak jde. Nicmene cilem je udelat z *.pbj instanci ShaderFilter
Comment by tom — March 8, 2009 @ 11:23 pm
Cavko, paradny clanok, ale neviem ako docielti pomocou tvojej tredy aby som nastavil dva a viac parametrov, danemu filtru napriklad
function applyRadius(radius:Number){
var transformObject2:Object = new Object();
transformObject2.outerRadius = 20
// PROSTE TOTO TO NEVIE SPRACOVAT A NEVIEM AKO TO ZAPISAT
transformObject2.center = [0,0];
pbl2.applyFilter(obrazok,transformObject2);
}
Comment by MISO — March 19, 2009 @ 10:19 am
//dalsi parametry posles velmi jednoduse:
var transformObject:Object = new Object();
transformObject.parametr1 = hodnota1;
transformObject.parametr2 = hodnota2;
// samotna aplikace:
pbl.applyFilter(deformClip,transformObject);
Comment by tom — March 24, 2009 @ 1:25 am
to ano ale ono mi to pride ze to neni osterene ked ma filtren na pariklad parameter center ktory sa sklada z dvoch suradnic napr
transformObject.center = [0,5]
alebo
transformObject.center[0] = 0
transformObject.center[1] = 5
tento zapis to uz nezobere
Comment by MISO — March 24, 2009 @ 10:13 pm
musis to zapsat takhle:
transformObject.center = new Array();
transformObject.center[0] = 0;
transformObject.center[1] = 5;
Comment by tom — March 27, 2009 @ 3:30 pm
dakujem moc
Comment by miso — March 29, 2009 @ 3:33 am
cavko po dlhom case som sa ktomu dostal a popisany postup mi nefunguje importujem triedu napisem :
var pbl:PixelBenderLoader = new PixelBenderLoader();
pbl.addEventListener(Event.COMPLETE,onComplete);
pbl.loadFilter(”pinch.pbj”);
function applyRadius(radius:Number){
// transformacni objekt, zmenime jen radius
var transformObject:Object = new Object();
transformObject.center = new Array();
//transformObject.magnification = radius;
transformObject.center[0] = 5;
transformObject.center[1] = 5;
// aplikuj filtr
pbl.applyFilter(deformClip,transformObject);
}
// zmen radius pri pohybu mysi
function mouseMoveChange(event:MouseEvent):void{
applyRadius(mouseX/500);
}
function onComplete(e:Event):void{
stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveChange);
}
a po spusteni hlasi chybu
ArgumentError: Error #2004: One of the parameters is invalid.
at flash.display::DisplayObject/set filters()
at PixelBenderLoader/applyFilter()
at omnio_fla::MainTimeline/applyRadius()
at omnio_fla::MainTimeline/mouseMoveChange()
Comment by Miso — April 10, 2009 @ 5:07 pm
fuu nejako zle to sformatovalo
Comment by Miso — April 10, 2009 @ 5:07 pm