Статьи

Создание пользовательских фильтров с помощью набора инструментов Pixel Bender

Два раза в месяц мы возвращаемся к любимым постам наших читателей на протяжении всей истории Activetuts +. Этот учебник был впервые опубликован в сентябре 2009 года.

Привет, еще раз, меня зовут Андре, и в этом уроке я продемонстрирую, как создавать собственные фильтры с помощью Pixel Bender Toolkit, а затем использовать их с Flash CS4 для вывода файлов .pbj.

* Эта функция работает только в Flash Player 10.


Pixel Bender Toolkit поставляется с пакетом Adobe Master Collection CS4 или вы можете загрузить его по адресу http://labs.adobe.com/downloads/pixelbender.html .


Прежде чем создавать какой-либо фильтр, мы должны понять основные функции и типы языка. Это отличается от Flash, и намного проще.

Ключевое слово ввода: это входное изображение , изображение, которое будет прочитано и обработано. В коде может быть до 2 входных изображений, работа с одним изображением создаст фильтр, а работа с 2 изображениями создаст режим наложения. На входе всегда используется тип «image4», который представляет собой изображение в режиме RGBA (красный, зеленый, синий и альфа).

Ключевое слово output: это выходной пиксель , а не входной. Это не будет выводить изображение, это будет просто выводить пиксель, считанный в RGBA. Это тип «pixel4» (а не image4 как ввод).

Ключевое слово параметра: ключевое слово параметра будет работать как функция установки. С помощью параметра значения фильтра могут быть изменены при использовании. Параметр должен сопровождаться типом и именем, а также может иметь минимальное значение, максимальное значение и значение по умолчанию. Пример: parameter int dimension <minValue:1; maxValue:10; defaultValue:1;>; parameter int dimension <minValue:1; maxValue:10; defaultValue:1;>; или parameter float myfloat <minValue:1.0; maxValue: 2.0; defaultValue: 1.0> parameter float myfloat <minValue:1.0; maxValue: 2.0; defaultValue: 1.0> parameter float myfloat <minValue:1.0; maxValue: 2.0; defaultValue: 1.0> . Также можно ввести параметр float2, float3, float3, int1, int2 … пример: parameter float2 test <minValue:float2(1.0,2.0);maxValue:float2(5);defaultValue:float2(1.0,2.0);>;

Также у нас есть типы float, float2, float3, float4, int, int2, int3, int4 и многие другие, которые мы здесь не будем использовать. Кроме того, некоторые типы не работают с Flash Player 10, поэтому я не буду вдаваться в них сейчас. Я, однако, немного расскажу о типах, которые я здесь упомянул, и о том, как они работают.

Введите float, float2, float3 и float4: например, когда вы создаете тип float4, вы создаете массив из 4 значений с плавающей точкой. В Pixelbender значения с плавающей точкой определяются точкой, но функция float () также работает как функция для преобразования других числовых значений с плавающей точкой. Например, "float4 test=float4(1,2,3,4);" , Здесь у нас есть объект с 4 значениями (тип float) в переменной «test». Вы также можете создать объект float4 из одного значения, например: "float4 test=float4(3);" , Здесь у нас есть объект с 4 значениями (RGBA), и все значения одинаковы (3.0 float). Когда вы создаете значение с плавающей точкой, вы также можете создать его, используя точку типа "float test=1.0;" , Если вы попытаетесь определить его как "float test=1;" это вызовет ошибку, потому что числа без точки в pixelbender работают как значения int.

Так что float всегда определяется точкой. Даже используя «float ()» для создания значения с плавающей точкой, вы получите число с точкой. Наконец, для доступа к значениям с плавающей запятой более чем с одним значением вы можете использовать синтаксис, такой как доступ к массиву «variable [0] или variable [1] или variable [2] …».

Типы int, int2, int3 и in4 — это то же самое, что и типы с плавающей точкой, но у них нет точек. Вы также можете конвертировать числовые значения, используя функции типа int.

evaluatePixel() : эта функция выполняется по всему изображению, пиксель за пикселем, а затем возвращает тип вывода pixel4. В пользовательских фильтрах для Flash мы всегда используем эту функцию.

outCoord() : эта функция возвращает текущую координату считываемого пикселя с помощью функцииvaluPixel. Он возвращает значения типа float2, значения x и y и может быть доступен [] как массив или .x и .y как объект. Например: var out = outCoord (); //out.x — это то же самое, что и out [0], а out.y — то же самое, что и out [1] .

sampleNearest(source,pixelCoordinate) : эта функция возвращает значение пикселя float4 из исходного изображения (image4) в координатах «pixelCoordinate». Обычно мы используем функцию «outCoord» здесь.

Наблюдение должно быть сделано; при использовании значений с плавающей запятой, и вы хотите добавить / вычесть / умножить или разделить значения с другими значениями с плавающей запятой той же длины, вы можете использовать их, как в этом примере:

1
2
3
float4 test1=float4(3.0,2.0,2.0,3.0);
float4 test2=float4(1.0,2.0,2.0,1.0);
float4 result=test1-test2;

Результатом будет переменная типа float4 со значениями 2.0, 0.0, 0.0 и 2.0. Также вы можете использовать:

1
2
3
4
5
float4 test1=float4(3.0,2.0,2.0,3.0);
float4 test2=float4(1.0,2.0,2.0,1.0);
float4 result=test1;
result[0]=test1[0]-test2[0];
result[2]-=0.5;

Я думаю, что этого достаточно, чтобы понять структуру кода Pixel Bender, давайте перейдем к следующему шагу, после того как я упомянул только еще одну вещь:

Перед тестированием любого фильтра важно загрузить хотя бы одно изображение (файл> загрузить изображение 1 «). Чтобы протестировать фильтр, вы можете перейти в build> run, если у фильтра есть какие-либо параметры, в правой части приложения, которое вы ‘ Вы увидите ползунки для изменения значений, они меняются во время выполнения и имеют предварительный просмотр в реальном времени, так как каждый раз, когда вы нажимаете, запускайте снова.


Этот фильтр поставляется с Pixel Bender Toolkit, но является одним из простых фильтров для объяснения. Для получения дополнительной информации о языке Pixel Bender просто нажмите кнопку F1 в программе, и откроется справка в формате .pdf.

После того, как программа открыта, создайте новый фильтр ядра (файл> новый фильтр ядра), программа создаст структуру фильтра по умолчанию:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
<languageVersion : 1.0;>
kernel NewFilter
< namespace : «Your Namespace»;
    vendor : «Your Vendor»;
    version : 1;
    description : «your description»;
>
{
    input image4 src;
    output pixel4 dst;
 
    void
    evaluatePixel()
    {
        dst = sampleNearest(src,outCoord());
    }
}

В ядре NewFilter вы меняете имя NewFilter на имя вашего фильтра. Пространство имен, поставщик, версия и описание мне не нужно объяснять, только ваши строки, такие как автор, версия (int) и описание.

Входное изображение будет изображением, загруженным фильтром, а выходным будет пиксель, сгенерированный функциейvaluPixel. Выводом будет значение pixel4, сгенерированное функциейvaluPixel, которая выполняет пиксель за пикселем входного изображения, как я объяснил.

В строке « dst = sampleNearest(src,outCoord()); » мы получаем значение текущего пикселя и координату outCoord () из изображения src (входное изображение), поэтому мы можем изменять значения rgba значение дст. Например, если мы хотим инвертировать цвета входного изображения, мы можем сделать следующее:

1
2
dst = sampleNearest(src,outCoord());
dst.rgb=float3(1)-dst.rgb;

Что мы здесь делаем?

Мы заявляем, что значение rgb этого пикселя является массивом значения float3 за вычетом исходного значения rgb, поэтому цвет будет инвертирован. Вы можете использовать dst.rgb вместо dst [0], dst [1] … и порядок после точки может быть любым, он будет читать каждую букву как значение цвета. Например, вы можете использовать dst.gbr = float3 (1) -dst.gbr. Еще вы можете попробовать изменить цвета изображения. Например, используя приведенный ниже код (внутри функцииifyPixel):

1
2
dst = sampleNearest(src,outCoord());
dst.rgb=dst.brg;

Этот код выведет странно окрашенное изображение.


Давайте протестируем фильтр от Adobe. Пиксельный фильтр отлично подходит для тестирования, поэтому перейдите в файл> открыть; в папке, где установлен Pixel Bender, есть несколько фильтров. Давайте выберем пиксельный фильтр. Когда он откроется, вы можете нажать кнопку «Выполнить», чтобы проверить фильтр. Если вы хотите экспортировать, перейдите в файл> Экспорт фильтра ядра для флэш-плеера. Это позволит экспортировать фильтр для использования с Flash. Вы можете загрузить фильтр с помощью URLLoader или встроить тег Embed из Flex SDK. В этом уроке я покажу, как работать со встроенным файлом, поскольку фильтр весит всего около 4–15 кБ (он очень легкий).

Выходное расширение — файл .pbj.


Если у вас есть classpath для Flash, используйте ваш classpath, если у вас его нет и вы хотите его создать, откройте мой предыдущий учебник и выполните шаг 1. Если вы не хотите classpath, используйте ту же папку вашего документа .fla , Давайте предположим, путь к классу для учебника.

В вашем classpath создайте папку «pixelbender». Затем внутри папки «pixelbender», внутри вашего classpath создайте папку «pbj». Скопируйте файл .pbj (пример: pixelate.pbj) в эту папку pbj, которую вы создали.


Откройте Flash CS4 или Flex с обновленным SDK для FP10. Если вы используете Flash, важно настроить Flex SDK для Flash. Если вы не знаете, как это сделать, нажмите «Ctrl + U», чтобы открыть настройки Flash, затем выберите «Actionscripts» в категории, а затем «Actionsctipt 3.0 settings». В окне «Дополнительные настройки Actionscript 3.0» нажмите кнопку «+» пути к библиотеке и добавьте следующее: $(FlexSDK)/frameworks/libs/flex.swc . Нажмите кнопку ОК.

Теперь создайте новый файл .as и начните кодировать следующее:

Сначала мы устанавливаем пакет и импортируем необходимые классы.

1
2
3
4
package pixelbender{
    import flash.display.Shader;
    import flash.filters.ShaderFilter;
    import flash.utils.ByteArray;

Создайте открытый класс PixelateFilter, расширяющий ShaderFilter. ShaderFilter может применяться как обычный фильтр в массиве фильтров любого объекта DisplayObject.

1
public class PixelateFilter extends ShaderFilter{

Вставьте файл pixelate.pbj в папку pbj (мы предполагаем, что мы сохраним файл .as в папке pixelate нашего classpath). Тег embed — это тег Flex, который вставляет файлы в SWF-файл вместо их загрузки. Есть много типов, которые вы можете встраивать, например .flv, .jpg и другие, и в качестве приложения / октета-потока mimeType файл будет встроен как ByteArray. Тег embed создает класс для встроенного файла, здесь я использую класс с именем «Filter».

1
[Embed(source=»pbj/pixelate.pbj»,mimeType=»application/octet-stream»)] private var Filter:Class;

В конструкторе давайте создадим экземпляр нашего встроенного файла как ByteArray. ByteArray — это параметр конструктора Shader, поэтому мы также создадим экземпляр шейдера, установив для фильтра значение «ByteArray» в качестве параметра конструктора. Поскольку мы расширяем ShaderFilter, нам не нужно создавать экземпляр ShaderFilter. Этот класс уже расширен ShaderFilter, поэтому все, что нам нужно сделать, это установить параметр shader нашего класса ShaderFilter в качестве экземпляра shader.

1
2
3
4
5
6
public function PixelateFilter():void
{
    var filter:ByteArray=new Filter() as ByteArray;
    var shader:Shader=new Shader(filter);
    this.shader=shader;
}

Теперь мы создаем новый параметр для нашего класса, параметр «измерение». Этот параметр будет влиять на «параметр int измерение», созданный в пикселбендере. Функция установки изменяет значение, а функция получения просто получает текущее значение. Доступ к значениям данных шейдера осуществляется через «instance.data.value», значения являются массивами. Если бы у нас был параметр «параметр int2 position;» в фильтре, например, мы будем обращаться к нему через «instance.data.position [0]» и «instance.data.position [1]» соответственно.

1
2
3
4
5
6
7
8
9
public function set dimension(value:Number):void
{
    shader.data.dimension.value[0]=value;
}
 
public function get dimension():Number
{
    return shader.data.dimension.value[0];
}

После всего этого просто закройте пакет и класс.

1
2
}
}

Теперь класс для этого фильтра создан, сохраните файл .as с именем «PixelateFilter.as» (то же имя, что и у класса) в папке pixelbender внутри вашего classpath (то же имя, что и у вашего пакета, и где вы также создал папку pbj).


Первый шаг, создайте новый документ .fla AS3, сохраните его где угодно, например, c: / mycustomfilter.

Определите класс для этого документа .fla. Откройте панель свойств документа .fla из окна> свойства, в поле «Класс» введите «Основной» и создайте новый файл ActionScript.

Скопируйте любое изображение в ту же папку документа .fla, например, я использовал одно из примеров изображений из примеров Pixel Bender; YellowFlowers.png, который можно найти с исходными файлами.

Если у вас еще нет класса TweenLite, загрузите его по адресу http://blog.greensock.com/tweenliteas3/ и распакуйте содержимое папки gs внутри папки gs в вашем пути к классам.

Создайте новый документ .as.

Включите необходимые классы в наш путь к классам:

1
2
3
4
5
package{
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import pixelbender.PixelateFilter;
    import gs.TweenLite;

Создайте класс Main, расширяющий класс Sprite:

1
public class Main extends Sprite{

Вставьте изображение для тестирования, mimeType — это «image / png», поэтому мы встраиваем как изображение, а не ByteArray. Назовите его класс «Img». Кроме того, мы вводим переменную с именем «filter» типа PixelateFilter, поэтому мы можем использовать ее позже в любой функции.

1
2
[Embed(source=»YellowFlowers.png»,mimeType=»image/png»)] private var Img:Class;
private var filter:PixelateFilter;

В конструкторе мы начинаем создавать наше изображение, на которое будет влиять фильтр, а затем добавляем дочернее изображение на сцену. Затем создайте экземпляр PixelateFilter. Мы создали переменную раньше, поэтому нам не нужно вводить снова. Установите размер фильтра равным 100, чтобы мы могли лучше видеть эффект, а также добавьте фильтр в список фильтров нашего основного класса.

Затем, используя класс TweenLite, мы анимируем параметр фильтра. Параметр измерения будет анимирован от 100 до 1. Во время обновления анимации выполняется функция «tweenLiteUpdate», а после завершения анимации будет выполняться функция «newTween».

1
2
3
4
5
6
7
8
public function Main():void{
    var image:Bitmap=new Img() as Bitmap;
    addChild(image);
    filter=new PixelateFilter();
    filter.dimension=100;
    this.filters=[filter];
    TweenLite.to(filter,3,{dimension:1,onUpdate:tweenLiteUpdate,onComplete:newTween});
}

В то время как TweenLite обновляется, tweenLiteUpdate выполняется и обновляет фильтр нашего класса Main. Без этого метода мы бы не увидели обновляющий фильтр TweenLite.

1
2
3
private function tweenLiteUpdate():void{
    this.filters=[filter];
}

Когда первая анимация анимации завершится, она запустит функцию newTween. Первая строка этой функции проверит, равно ли значение измерения фильтра 1. Если это так, он установит переменную dim на 100, иначе он установит переменную на 1. Это то же самое, что и if и else, или switch. Вторая строка снова запустит анимацию анимации фильтра.

1
2
3
4
private function newTween():void{
    var dim:Number=(filter.dimension==1)?100:1;
    TweenLite.to(filter,3,{dimension:dim,onUpdate:tweenLiteUpdate,onComplete:newTween});
}

Теперь просто закройте пакет и класс с двойным «}».

1
2
}
}

Сохраните ваш файл как «Main.as» в той же папке вашего .fla файла, и если все файлы и папка в порядке, вы можете проверить ваш файл. Анимация начнет пикселироваться, перейдет в обычное изображение и будет непрерывно повторяться.


Надеюсь, вам понравилось, и надеюсь, это будет очень полезно. В Adobe Exchange есть множество других фильтров, которые вы можете скачать, некоторые из них бесплатны или имеют открытый исходный код. Я также поместил некоторые другие .pbj и классы с источником для изучения. Например, SpherizeFilter.as: http://cavallari.freehostia.com/spherize/ , анимирует положение мыши.