Использование шейдера в качестве графического фильтра

Flash Player 10 и более поздних версий, Adobe AIR 1.5 и более поздних версий

Использование шейдера в качестве графического фильтра подобно использованию других фильтров в ActionScript. Когда шейдер применяется в качестве фильтра, ему передается фильтруемое изображение (экранный объект или объект BitmapData). Шейдер использует входное изображение для создания вывода фильтра, который обычно представляет собой измененную версию исходного изображения. Если фильтруемое изображение является экранным объектом, вывод шейдера отображается на экране вместо него. Если фильтруемый объект является объектом BitmapData, результат шейдера становится содержимым объекта BitmapData, для которого вызван метод applyFilter() .

Для использования шейдера в качестве фильтра сначала нужно создать объект Shader, как описано в разделе Загрузка или встраивание шейдера . После этого нужно создать объект ShaderFilter, связанный с объектом Shader. Объект ShaderFilter представляет собой фильтр, который применяется к фильтруемому объекту. Он применяется к объекту так же, как и обычный фильтр. Этот объект передается свойству filters экранного объекта или методу applyFilter() , вызываемому для объекта BitmapData. Например, следующий код создает объект ShaderFilter и применяет фильтр к экранному объекту с именем homeButton .

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

При использовании шейдера в качестве фильтра необходимо определить хотя бы одно значение ввода. Как показано в примере, код не задает значения ввода. Вместо этого, в качестве входного изображения задается фильтруемый экранный объект или объект BitmapData. Если используется шейдер, который ожидает больше одного входного изображения, необходимо задать остальные значения.

В некоторых случаях фильтр изменяет размеры исходного изображения. Например, типичный эффект тени добавляет к изображению дополнительные пикселы, содержащие тень. При использовании шейдера, который меняет размеры изображения, необходимо задать свойства leftExtension , rightExtension , topExtension и bottomExtension , чтобы указать, насколько должен измениться размер изображения.

Следующий пример демонстрирует использование шейдера в качестве фильтра. Фильтр инвертирует значения красного, зеленого и синего каналов изображения. Результат представляет собой «негатив» изображения.

Примечание. В данном примере в качестве шейдера используется ядро Pixel Bender invertRGB.pbk, которое включено в Pixel Bender Toolkit. Исходный код этого ядра можно загрузить в каталоге установки Pixel Bender Toolkit. Скомпилируйте исходный код и сохраните файл байт-кода в том же каталоге, что исходный код ActionScript.

Основной код ActionScript строится на двух методах.

  • init() : метод init() вызывается при загрузке приложения. В этом методе код загружает файл байт-кода шейдера.

  • onLoadComplete() : в методе onLoadComplete() код создает объект Shader с именем shader . Затем он создает и отрисовывает содержимое объекта target . Объект target представляет собой прямоугольник, заполненный линейным градиентом цвета: красный слева, желто-зеленый в середине и голубой справа. Нефильтрованный объект выглядит так:

    После применения фильтра цвета инвертируются, и прямоугольник выглядит так:

В данном примере в качестве шейдера используется ядро Pixel Bender «invertRGB.pbk», которое включено в Pixel Bender Toolkit. сходный код находится в файле «invertRGB.pbk» в каталоге установки Pixel Bender Toolkit. Скомпилируйте исходный код и сохраните файл байт-кода с именем «invertRGB.pbj» в той же папке, что исходный код ActionScript.

Ниже приводится код ActionScript для этого примера. Используйте этот класс в качестве основного класса приложения для проекта, созданного только на базе ActionScript в Flash Builder, или в качестве класса документа для FLA-файла в инструменте Flash Professional.

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]; 
        } 
    } 
}

Дополнительные сведения о применении фильтров см. в разделе Создание и применение фильтров .