天天看點

PixelBender(着色器)初體驗

隻要是玩過photoshop的人,一定會對ps中的各式各樣、功能強大的濾鏡(filter)留下深刻的印象。 Adobe是靠圖形處理軟體起家的,這方面一直是它的強項。這一技術經過不斷發展,最終形成了今天的Pixel Bender(官方翻譯為"着色器"),它在Adobe CS系列的主要産品中都被良好支援(包括Flash),而且據官方的介紹pixel bender支援GPU,多線程.

下面是幾個在Flash中使用pixelBender的示例:

1.RGB色彩反相(有點象底片效果)

package {

  import flash.display.*;
  import flash.events.*;
  import flash.filters.*;
  import flash.net.*;
  import flash.utils.ByteArray;

  [SWF(width="300",height="450",backgroundColor="#000000",framerate="30")]
  public class Demo1 extends Sprite {

    [Embed("invertRGB.pbj",mimeType="application/octet-stream")]
    private var TestFilter:Class;

    [Embed(source="mm1.png")]
    private var image:Class;
    private var im:Bitmap;
    private var btnAdd:FlatButton;
    private var isApply:Boolean=false;

    public function Demo1():void {
      im=new image   as Bitmap;
      addChild(im);
      btnAdd = new FlatButton();
      addChild(btnAdd);
      btnAdd.scaleX=btnAdd.scaleY=1.5;
      btnAdd.x=stage.stageWidth/2;
      btnAdd.y=25;
      btnAdd.addEventListener(MouseEvent.CLICK,btnAddClickHandler);
    }

    function btnAddClickHandler(e:MouseEvent):void {
      if (! isApply) {
        var shader:Shader = new Shader(new TestFilter() as ByteArray);
        var filter:ShaderFilter=new ShaderFilter(shader);
        im.filters=[filter];
        isApply=true;
      } else {
        im.filters=[];
        isApply=false;
      }
    }
  }
}
      

2.變色效果

package {

  import flash.display.*;
  import flash.events.*;
  import flash.filters.*;
  import flash.net.*;
  import flash.utils.ByteArray;
  import fl.controls.*;
  import fl.events.SliderEvent;

  [SWF(width="300",height="450",backgroundColor="#000000",framerate="30")]
  public class Demo2 extends Sprite {

    [Embed("sepia.pbj",mimeType="application/octet-stream")]
    private var TestFilter:Class;

    [Embed(source="mm1.png")]
    private var image:Class;
    private var im:Bitmap;
    private var sl:Slider;

    public function Demo2():void {
      im=new image   as Bitmap;
      addChild(im);
      sl = new Slider();
      addChild(sl);
      sl.scaleX=sl.scaleY=2.0;
      sl.x=stage.stageWidth/2-sl.width/2;
      sl.y=20;
      sl.minimum=-1.0;
      sl.maximum=1.0;
      sl.snapInterval=0.05;
      sl.addEventListener(SliderEvent.THUMB_DRAG,changeHandler);
    }

    function changeHandler(e:SliderEvent):void {
      var shader:Shader = new Shader(new TestFilter() as ByteArray);      
      shader.data["intensity"].value[0] = e.value;
      var filter:ShaderFilter=new ShaderFilter(shader);     
      im.filters=[filter];
    }
  }
}
      

3.馬賽克效果

package {

  import flash.display.*;
  import flash.events.*;
  import flash.filters.*;
  import flash.net.*;
  import flash.utils.ByteArray;
  import fl.controls.*;
  import fl.events.SliderEvent;

  [SWF(width="300",height="450",backgroundColor="#000000",framerate="30")]
  public class Demo3 extends Sprite {

    [Embed("pixelate.pbj",mimeType="application/octet-stream")]
    private var TestFilter:Class;

    [Embed(source="mm1.png")]
    private var image:Class;
    private var im:Bitmap;
    private var sl:Slider;

    public function Demo3():void {
      im=new image   as Bitmap;
      addChild(im);
      sl = new Slider();
      addChild(sl);
      sl.scaleX=sl.scaleY=2.0;
      sl.x=stage.stageWidth/2-sl.width/2;
      sl.y=20;
      sl.minimum=1;
      sl.maximum=50;
      sl.snapInterval=1;
      sl.addEventListener(SliderEvent.THUMB_DRAG,changeHandler);
    }

    function changeHandler(e:SliderEvent):void {
      var shader:Shader = new Shader(new TestFilter() as ByteArray);      
      shader.data["dimension"].value[0] = e.value;
      var filter:ShaderFilter=new ShaderFilter(shader);     
      im.filters=[filter];      
    }
  }
}
      

4.扭曲效果

package {

  import flash.display.*;
  import flash.events.*;
  import flash.filters.*;
  import flash.net.*;
  import flash.utils.ByteArray;
  import fl.controls.*;
  import fl.events.SliderEvent;

  [SWF(width="300",height="450",backgroundColor="#000000",framerate="30")]
  public class Demo4 extends Sprite {

    [Embed("twirl.pbj",mimeType="application/octet-stream")]
    private var TestFilter:Class;

    [Embed(source="mm1.png")]
    private var image:Class;
    private var im:Bitmap;
    private var slRadius:Slider;
    private var slCenterX:Slider;
    private var slCenterY:Slider;
    private var sAngle:Slider;

    public function Demo4():void {
      im=new image   as Bitmap;
      addChild(im);
      slRadius = new Slider();
      slCenterX = new Slider();
      slCenterY = new Slider();
      sAngle = new Slider();

      addChild(slRadius);
      addChild(slCenterX);
      addChild(slCenterY);
      addChild(sAngle);
      slRadius.scaleX=slRadius.scaleY=slCenterX.scaleX=slCenterX.scaleY=slCenterY.scaleX=slCenterY.scaleY=sAngle.scaleX=sAngle.scaleY=2.0;
      slRadius.x=stage.stageWidth/2-slRadius.width/2;
      slRadius.y=20;      
      slCenterX.x = slRadius.x;
      slCenterX.y = slRadius.y + 20;
      slCenterY.x = slRadius.x;
      slCenterY.y = slCenterX.y + 20;
      sAngle.x = slRadius.x;
      sAngle.y = slCenterY.y + 20;
      
      slRadius.minimum=10;
      slRadius.maximum=290;
      slRadius.snapInterval=1;
      
      slCenterX.minimum=0;
      slCenterX.maximum=300;
      slCenterX.snapInterval=1;
      
      slCenterY.minimum=0;
      slCenterY.maximum=450;
      slCenterY.snapInterval=1;
      
      sAngle.minimum=0;
      sAngle.maximum=360;
      sAngle.snapInterval=1;
      sAngle.value = 90;
      
      
      slRadius.addEventListener(SliderEvent.THUMB_DRAG,slRadiusHandler);      
      slCenterX.addEventListener(SliderEvent.THUMB_DRAG,slRadiusHandler);
      slCenterY.addEventListener(SliderEvent.THUMB_DRAG,slRadiusHandler);
      sAngle.addEventListener(SliderEvent.THUMB_DRAG,slRadiusHandler);
    }

    function slRadiusHandler(e:SliderEvent):void {
      var shader:Shader = new Shader(new TestFilter() as ByteArray);
      shader.data["twirlAngle"].value[0]=sAngle.value;
      shader.data["center"].value[0]=slCenterX.value;
      shader.data["center"].value[1]=slCenterY.value;
      shader.data["radius"].value[0]=slRadius.value;
      var filter:ShaderFilter=new ShaderFilter(shader);
      im.filters=[filter];
    }
  }
}
      

5.混合過渡效果

package {

  import flash.display.*;
  import flash.events.*;
  import flash.filters.*;
  import flash.net.*;
  import flash.utils.ByteArray;
  import fl.controls.*;


  [SWF(width="300",height="450",backgroundColor="#000000",framerate="30")]
  public class Demo5 extends Sprite {

    [Embed("crossfade.pbj",mimeType="application/octet-stream")]
    private var TestFilter:Class;

    [Embed(source="mm1.png")]
    private var image:Class;

    [Embed(source="mm2.jpg")]
    private var image2:Class;

    private var im:Bitmap;
    private var im2:Bitmap;
    private var sl:Slider;


    public function Demo5():void {
      im=new image   as Bitmap;
      im2=new image2   as Bitmap;
      addChild(im);
      addChild(im2);
      sl = new Slider();
      addChild(sl);
      sl.minimum=0;
      sl.maximum=1;
      sl.snapInterval=0.01;
      sl.value=1;
      sl.scaleX=sl.scaleY=2.0;
      sl.x=stage.stageWidth/2-sl.width/2;
      sl.y=20;
      addEventListener(Event.ENTER_FRAME,enterFrameHandler);
    }

    function enterFrameHandler(e:Event):void {
      var shader:Shader = new Shader(new TestFilter() as ByteArray);
      shader.data.frontImage.input=im2.bitmapData;
      shader.data.backImage.input=im.bitmapData;
      shader.data["intensity"].value[0]=sl.value;
      im2.blendMode=BlendMode.SCREEN;//這一句加上後,好象容易引起Flash崩潰,但不加這一句,又無法實時重新整理。
      im2.blendShader=shader;
    }
  }
}
      

 以上效果都是PixelBender ToolKit自帶的,如果您想開發自己想要的效果,Adobe也提供了詳細的線上教程友善開發者學習。

 ​

作者:菩提樹下的楊過