使用着色器作为滤镜

Flash Player 10 和更高版本,Adobe AIR 1.5 和更高版本

使用着色器作为滤镜与在 ActionScript 中使用任何其他滤镜类似。使用着色器作为滤镜时,过滤出的图像(显示对象或 BitmapData 对象)将传递给着色器。着色器使用输入图像来创建滤镜输出,该输出通常为原始图像经过修改的版本。如果过滤出的对象是显示对象,着色器输出将显示在屏幕上,代替过滤出的显示对象。如果过滤出的对象是 BitmapData 对象,着色器输出将成为 BitmapData 对象的内容,并调用该对象的 applyFilter() 方法。

若要使用着色器作为滤镜,您首先要创建 Shader 对象,如 加载或嵌入着色器 中所述。接下来,您需要创建链接到该 Shader 对象的 ShaderFilter 对象。ShaderFilter 对象便是将应用到所过滤对象的滤镜。将滤镜应用于对象的方式与应用任何滤镜的方式相同。将其传递给显示对象的 filters 属性,或者对 BitmapData 对象调用 applyFilter() 方法。例如,下面的代码创建 ShaderFilter 对象,并将此滤镜应用到名为 homeButton 的显示对象。

var myFilter:ShaderFilter = new ShaderFilter(myShader); 
homeButton.filters = [myFilter];

在使用着色器作为滤镜时,着色器必须由至少一个输入定义。如示例所示,您未在代码中设置输入值。而是将过滤出的显示对象或 BitmapData 对象设置为输入图像。如果所用着色器要求一个以上的输入,则还需为第一个之外的其他输入提供值。

在某些情况下,滤镜会改变原始图像的尺寸。例如,典型的投影效果会添加额外的像素,这些像素组成为图像添加的阴影。在使用更改图像尺寸的着色器时,需设置 leftExtension rightExtension topExtension bottomExtension 属性,指明所需图像尺寸更改量。

下面的示例演示如何使用着色器作为滤镜。此示例中的滤镜将反转图像红绿蓝三色通道的值。其结果为该图像的“负片”版本。

注: 此示例使用的着色器为 Pixel Bender 工具包中附带的 invertRGB.pbk Pixel Bender 内核。您可以从 Pixel Bender 工具包安装目录中加载此内核的源代码。编译源代码,然后将字节代码文件保存到源代码所在的目录。

这段重要的 ActionScript 代码用到下面两个方法:

  • init() :应用程序加载时调用 init() 方法。在此方法中,代码加载着色器字节代码文件。

  • onLoadComplete() :在 onLoadComplete() 方法中,代码创建名为 shader 的 Shader 对象。然后创建并绘制名为 target 的对象的内容。 target 对象是用线性渐变色填充的矩形:左边是红色,中间是黄绿色,右边是淡蓝色。未过滤的对象看上去是这样:

    应用了滤镜后,颜色反转,矩形变成这样:

此示例使用的着色器为 Pixel Bender 工具包中附带的“invertRGB.pbk”Pixel Bender 范例内核。源代码位于 Pixel Bender 工具包安装目录的“invertRGB.pbk”文件中。编译源代码,然后以文件名“invertRGB.pbj”将字节代码文件保存在 ActionScript 源代码所在的目录中。

下面是此示例的 ActionScript 代码。使用此类作为 Flash Builder 中纯 ActionScript 项目的主应用程序类,或者作为 Flash Professional 中 FLA 文件的文档类:

package 
{ 
    import flash.display.GradientType; 
    import flash.display.Graphics; 
    import flash.display.Shader; 
    import flash.display.Shape; 
    import flash.display.Sprite; 
    import flash.filters.ShaderFilter; 
    import flash.events.Event; 
    import flash.geom.Matrix; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
     
    public class InvertRGB extends Sprite 
    { 
        private var shader:Shader; 
        private var loader:URLLoader; 
         
        public function InvertRGB() 
        { 
            init(); 
        } 
         
        private function init():void 
        { 
            loader = new URLLoader(); 
            loader.dataFormat = URLLoaderDataFormat.BINARY; 
            loader.addEventListener(Event.COMPLETE, onLoadComplete); 
            loader.load(new URLRequest("invertRGB.pbj")); 
        } 
         
         
        private function onLoadComplete(event:Event):void 
        { 
            shader = new Shader(loader.data); 
             
            var target:Shape = new Shape(); 
            addChild(target); 
             
            var g:Graphics = target.graphics; 
            var c:Array = [0x990000, 0x445500, 0x007799]; 
            var a:Array = [255, 255, 255]; 
            var r:Array = [0, 127, 255]; 
            var m:Matrix = new Matrix(); 
            m.createGradientBox(w, h); 
            g.beginGradientFill(GradientType.LINEAR, c, a, r, m); 
            g.drawRect(10, 10, w, h); 
            g.endFill(); 
             
            var invertFilter:ShaderFilter = new ShaderFilter(shader); 
            target.filters = [invertFilter]; 
        } 
    } 
}

有关应用滤镜的详细信息,请参阅 创建和应用滤镜