Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
  1. Code
  2. Effects

Create Custom Filters Using the Pixel Bender Toolkit


Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in September, 2009.

Hi, once again, my name is André and in this tutorial I'll demonstrate how to create custom filters with the Pixel Bender Toolkit, then use them with Flash CS4 to output .pbj files.

* This feature works only in Flash Player 10.

Step 1: The Pixel Bender Toolkit

The Pixel Bender Toolkit comes with the Adobe Master Collection CS4 pack, or you can download it at http://labs.adobe.com/downloads/pixelbender.html.

Step 2: The Basics

Before creating any filter, we must understand the basic functions and types of the language. It's different to Flash, and much simpler.

The input keyword: This is the input image, the image that will be read and worked on. We can have up to 2 input images in the code, working with one image will create a filter, and working with 2 images will create a blend mode. The input is always type of "image4", which is an image in RGBA mode (Red, Green, Blue and Alpha).

The output keyword: This is the output pixel, as opposed to the input. This will not output the image, this will just output the pixel read in RGBA. This is type "pixel4" (and not image4 like the input).

The parameter keyword: Parameter keyword will work like a setter function. With the parameter the values of the filter can be changed when in use. The parameter must be followed by the type and name, and can also have minimum value, maximum value and default value. Example: parameter int dimension <minValue:1; maxValue:10; defaultValue:1;>; or parameter float myfloat <minValue:1.0; maxValue: 2.0; defaultValue: 1.0>. Also the parameter can be typed float2, float3, float3, int1, int2... example: parameter float2 test <minValue:float2(1.0,2.0);maxValue:float2(5);defaultValue:float2(1.0,2.0);>;

Also we have the types float, float2, float3, float4, int, int2, int3, int4 and many others which we will not use here. Also, some types don't work with Flash Player 10, so I won't get into them right now. I will, however, discuss a little bit about the types I've mentioned here and how they work.

Type float, float2, float3 and float4: when you create a float4 type for example, you are creating an array of 4 float values. In Pixelbender the float values are define by dot, but float() also works like a function to convert other number values in float. For example "float4 test=float4(1,2,3,4);". Here we have an object with 4 values (type float) in "test" variable. You can also create a float4 object from one value, for example: "float4 test=float4(3);". Here we have an object with 4 values (RGBA) and all values are the same (3.0 float). When you create a float value, you can also create it using a dot like "float test=1.0;". If you try to define it like "float test=1;" it will throw an error, because numbers without a dot in pixelbender work like int values.

So float are always defined by dot. Even using "float()" to create the float value will return a number with a dot. Lastly, to access float values with more than one value you can use syntax like an array access " variable[0] or variable[1] or variable[2] ... ".

Type int, int2, int3 and in4 are the same thing as float types, but don't have dots. You can also convert number values using "int" like functions.

evaluatePixel(): this function runs over all the image, pixel by pixel, and then returns the output type pixel4. In custom filters for Flash we always use this function.

outCoord(): this function returns the current coordinate of the pixel being read by the evaluatePixel function. It returns a value type float2, x and y values, and can be accessed by [] like array or .x and .y like object. For example: var out=outCoord(); //out.x is the same of out[0] and out.y is the same of out[1].

sampleNearest(source,pixelCoordinate): this function returns the float4 value of the pixel from the source image (image4) at the coordinations "pixelCoordinate". Normally we use the "outCoord" function here.

An observation must be made; when using float values and you want to add/subtract/multiply or divide the values with other float value of the same length, you can use them like this example:

The result will be a variable type float4 with values 2.0, 0.0, 0.0 and 2.0. Also, you could use:

I think this is enough to understand the structure of Pixel Bender code, let's move onto the next step, after I've mentioned just one more thing:

Before testing any filter, it's important to load at least one image (file > load image 1"). To test the filter you can go to build > run, if the filter has any parameters, on the right side of the application you'll see sliders to change the values. They change at runtime and have a live preview, since each time you press run again.

Step 3: Create a New Pixel Bender Filter

This filter comes with Pixel Bender Toolkit, but is one of the simpler filters to explain. For more about the Pixel Bender language reference just hit F1 button in the program, and the help in .pdf will open.

Once the program is open, create a new Kernel Filter (file > new kernel filter) the program will create a default structure for the filter:

In kernel NewFilter, you change the name NewFilter for the name of your filter. Namespace, vendor, version and description I don't need to explain, just your strings like author, version (int) and the description.

The input image will be the image loaded by the filter and the output will be the pixel generated by the evaluatePixel function. The output will be a pixel4 value generated by the evaluatePixel function, which runs pixel by pixel of the input image as I've explained.

At the line "dst = sampleNearest(src,outCoord());" we are getting the value of the current pixel, and the coordinate outCoord() from image src (the input image), so we can modify the values of the rgba value of the dst. For example, if we want to invert the colours of the input image, we could do the following:

What are we doing here?

We are stating that the rgb value of this pixel is the array of float3 value less the original value of rgb, so the color will be inverted. You can use the dst.rgb instead of using dst[0], dst[1]... and the order after the dot can be any order, it will read each letter as the value of the color. For example, you can use dst.gbr=float3(1)-dst.gbr. Another thing you can try is to change the colours of the image. For example by using the code below (inside the evaluatePixel function):

This code will output an oddly coloured image.

Step 4: Testing a Prepared Code From Adobe

Let's test a filter from Adobe. The pixelate filter is great for testing, so go to file > open; in the folder where Pixel Bender is installed there are some filters. Let's choose the pixelate filter. Once it's open you can hit the "run" button to test the filter. If you want to export, go to file > Export kernel filter for flash player. This will export the filter to use with Flash, you can load the filter with the URLLoader or embed with the Embed tag from Flex SDK. In this tutorial I will show how to work with the embedded file, since the filter weighs only about 4kb to 15kb (it's very lightweight).

The output extension is a .pbj file.

Step 5: Create the Folder Structure

If you have a classpath for Flash, use your classpath, if you dont have one and want to create one, open my previous tutorial and follow Step 1. If you don't want a classpath, use the same folder of your .fla document. Let's assume the classpath for the tutorial.

In your classpath create the folder "pixelbender". Then inside the "pixelbender" folder, inside your classpath create the folder "pbj". Copy the .pbj file (example: pixelate.pbj) to this pbj folder you've created.

Step 6: Creating the Class for the Pixelate Filter

Open Flash CS4, or Flex with updated SDK for FP10. If you're using Flash, it's important to setup the Flex SDK for Flash. If you don't know how to do this, hit "ctrl+u" to open the preferences of Flash, then select the "actionscripts" at category, then "Actionsctipt 3.0 settings". In the window "Actionscript 3.0 advanced settings" click the "+" button of the library path and add the following: $(FlexSDK)/frameworks/libs/flex.swc. Click the OK button.

Now create a new .as file, and start coding the following:

First we set the package and import the necessary classes.

Create the public class PixelateFilter extending the ShaderFilter. The ShaderFilter can be applied as a normal filter in the filter array of any DisplayObject.

Embed the pixelate.pbj file in the folder pbj (we're assuming that we'll save the .as in the pixelate folder of our classpath). The embed tag is a Flex tag which embeds files in a swf instead of loading them. There are lots of types that you can embed, like .flv, .jpg and others, and as mimeType application/octet-stream the file will be embedded as ByteArray. The embed tag creates a class for the embedded file, here I'm using a class named "Filter".

In the constructor, let's create an instance of our embedded file as ByteArray. The ByteArray is the Shader constructor's parameter, so we'll also create the shader instance, setting the filter to "ByteArray" as the parameter of the constructor. Since we're extending the ShaderFilter, we don't need to create an instance of the ShaderFilter. This class is already ShaderFilter extended, so all we need to do is set the shader parameter of our ShaderFilter class as the shader instance.

Now we create a new parameter for our class, the parameter "dimension". This parameter will affect the "parameter int dimension" created in the pixelbender. The setter function will alter the value, and the getter function will just get the current value. The shader data values can be accessed by "instance.data.value", the values are arrays. If we had a parameter "parameter int2 position;" in the filter for example, we would access it by "instance.data.position[0]" and "instance.data.position[1]" respectively.

After all that, just close the package and the class.

Now the class for this filter is created, save the .as file with the name "PixelateFilter.as" (the same name as the class) in the pixelbender folder inside your classpath (same name as your package, and where you've also created the pbj folder).

Step 7: Test the New Filter

First step, create a new .fla AS3 document, save it anywhere you want, for example c:/mycustomfilter.

Define a class for this .fla document. Open the properties panel of the .fla document from the window > properties, in the box "Class" type "Main", and create a new actionscript file.

Copy any image to the same folder of the .fla document, for example I've used one of the sample images from the Pixel Bender examples; YellowFlowers.png, which can be found with the source files.

If you don't have the TweenLite class yet, please download it at http://blog.greensock.com/tweenliteas3/, and unpack the contents of gs folder inside the gs folder in your classpath.

Create a new .as document.

Include the necessary classes to our classpath:

Create the Main class extending the Sprite class:

Embed the image for testing, the mimeType is "image/png", so we're embedding as image not ByteArray. Name its class "Img". Additionally, we type a variable named "filter" of the type PixelateFilter, so we can use it in any function later on.

In the constructor, we start creating our image, which will be affected by the filter, then add the image child to the stage. Then create instance of PixelateFilter. We've created the variable before, so we don't need to type again. Set the filter dimension to 100, so we can see the effect better, also add the filter to the filterlist of our Main class.

Then using the TweenLite class we animate the filter parameter. The dimension parameter will be animated from 100 to 1. While the animation is being updated, the function "tweenLiteUpdate" is executed, and when it's finished animating the "newTween" function will be executed.

While TweenLite is being updated, the tweenLiteUpdate is executed and updates the filter of our Main class. Without this method we wouldn't see the TweenLite updating the filter.

When the first Tweening animation completes, it will run the newTween function. The first line of this function will check if the filter dimension value is 1. If so, it will set the dim variable to 100, else it'll set the variable to 1. This is the same with if and else, or switch. The second line will start the Tweening animation of the filter again.

Now just close the package and the class with double "}".

Save your file as "Main.as" in the same folder of your .fla file, and if all files and folder are OK, you can test your file. The animation will start pixelated, changing to the normal image, and will loop continuously.


I hope you liked this, and I hope it will be very useful. In Adobe Exchange there are a lot of other filters you can download, some of them are free or open source. I've also put some other .pbj and classes with the source for studying. For example, SpherizeFilter.as: http://cavallari.freehostia.com/spherize/, animates by the position of the mouse.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.