Using the Displacement Filter in Adobe Flash
Create Some Noise
To become proficient at Flash you need to learn how to utilize the amazing community we have for inspiration and code samples. This tutorial will show you how to bring a still photo to life using the mysterious displacement map filter and some Perlin noise. Completely understanding this filter isn’t necessary in order to achieve some stunning effects with it. What is important however, is the ability to take some example code and experiment with it until you achieve the effect that you’re looking for.
If you’d like to download the files used in this tutorial to practice these techniques, visit www.layersmagazine.com and navigate to the Magazine section. All files are for personal use only.
1 OPEN THE PSD FILE
For this tutorial we’ll work with this photo of a canal in Amsterdam and we’ll make the water come to life. Open the water.psd file from the tutorial folder in Photoshop CS3 so we can take a look at the layer structure. This file contains two layers with the photo on each layer. The original layer contains the untouched photo. The other layer contains the same photo except the canal has been masked out. Once we get into Flash we’ll apply the filter effect to the bottom layer; only the water of that layer will be visible under the masked layer.
CREDIT: LEE BRIMELOW
2 OPEN THE FLA FILE
Now open the water.fla file from the tutorial folder in Flash CS3. This file was set up by creating a new ActionScript 3.0 document, setting the frame rate to 30, resizing the stage to the photo’s size, and renaming the first layer to actions and locking it. It’s important to note that all the techniques we’ll show you here are also available in ActionScript 2.0 but there will be considerable performance increases if you use the latest version of the language.
3 IMPORT THE PSD FILE
In Flash, select File>Import>Import to Library to open the import dialog. Select the water.psd file and click the Import to Library button to open the PSD importer. Here you can adjust the settings that affect how the Photoshop file is imported. Click the masked layer and under Publish Settings change the Quality to Custom: 90. Now select the original layer and click the Create Movie Clip for This Layer checkbox. Also set the Quality of this layer to Custom: 90. Click OK to complete the import.
4 LAYING OUT THE ASSETS
Click the Insert Layer icon to create a new layer above the actions layer. Double-click on the layer’s name and rename it photo. In the Library panel (Window>Library), go into the water.psd Assets folder by double-clicking it, and drag out a copy of the original movie clip onto the stage. In the Property inspector (Window>Properties>Properties), set its X and Y values both to zero and give it an Instance Name of photo. Create another new layer and name it masked. Drag out a copy of the masked image from the Library panel onto the stage and position it to X:0, Y:0 in the Property inspector. You can now lock all of the layers on the Timeline.
5 START WRITING THE CODE
Now that we’ve taken care of the entire visual layout, it’s time to start writing the ActionScript code that will turn the photo of the canal into a beautiful moving animation. Select the first keyframe in the actions layer and then open the Actions panel by selecting Window>Actions. One helpful tip for working with the Actions panel is to pin your script so that your code will always be visible no matter what you’re clicking on. Click on the Pin Active Script (pushpin) icon to pin the main script into the Actions panel.
6 CREATE THE DISPLACEMENT FILTER
Copy the code you see above into your Actions panel. On line 1, we create an instance of the BitmapData class that will allow the filter to manipulate our image on a pixel-level basis and we set its width and height to the same as our photo. On line 2 we create an instance of the DisplacementMapFilter and pass to it the BitmapData object we created on line 1. You can look in the help files to see what the rest of the parameters do. As always, experimentation is key here.
7 SOME PERLIN PROPERTIES
We’ll use something called Perlin noise to create the water effect. (You can read more about Perlin noise at the end of this tutorial.) In order to use this we need to create a few variables that the Perlin noise function requires. Copy the code you see above into the Actions panel. On lines 4 and 5 we create a couple of Point objects. These are objects that contain an X and Y position. On line 6, we create a new Array that will hold the two Point objects. An Array is simply an object that holds other objects.
8 SET UP THE EVENT
In order for us to make the water move we’ll need to apply the displacement filter continuously in a loop, altering some of its properties as we go. To create a loop we need to set up the ENTER_FRAME event. This event calls a function every time the player hits a new frame. Since we set our movie to 30 fps, the function will be called 30 times a second. Copy the code you see above into the Actions panel. It creates a new ENTER_FRAME event and tells it to call the loop function every time it fires.
9 CREATE THE LOOP FUNCTION
In the last step we told the ENTER_FRAME event to call the loop function each time it fires. In this step we’ll actually create this function. Copy the code you see above into the Actions panel. This code creates a new function named loop. Inside of this we’ll adjust properties of the displacement filter and then apply this filter to our photo movie clip. Again, if some of this is confusing don’t worry. The beauty of Flash is that you don’t need to understand all of the code in order to use it!
10 INCREMENT THE OFFSETS
Enter the code you see above into the Actions panel. On lines 12 and 13 we made increments for the Point objects we created earlier. Changing these two values can create a wide array of different effects. (The values I chose here were based on my experimenting until a realistic water effect was reached.) Line 12 controls the effect on the X axis and line 13 the Y axis. These values will change 30 times a second and are what causes the displacement filter to do its magic.
11 CREATE SOME NOISE
Copy this line of code shown above into the Actions panel, which calls the perlinNoise function on the bitmap data object we created in Step Six. This function takes a slew of parameters and it’s not important that you understand what each of them does. The main thing to take notice of is that we pass in the perlinOffset object that we manipulated in the previous step. (I definitely recommend that you look up perlinNoise in the help files to learn more about what each of the parameters does.)
12 APPLY THE FILTER
The last step needed to make this effect work is to simply apply the displacement filter to the photo movie clip. Copy the code shown above into the Actions panel. Here we’re setting the filter to the movie clip’s filters property. We use square brackets since the filters property is actually an Array designed to hold multiple filters. Test your movie and you should now see the canal come to life. I’m still amazed how realistic this effect looks. If you added some ambient sound people would swear it was video footage.
More About Perlin Noise
As mentioned in the tutorial, generating Perlin noise is the key to making this technique work. It’s also vital in the creation of hundreds of other effects like fire, smoke, and clouds. Perlin noise is named after its creator, Ken Perlin, who created the algorithm while doing the special effects for the movie Tron. He won the Academy Award for Technical Achievement in 1997. The actual math behind this technique can get quite complex but if you want to learn more about it you can point your browser at http://en.wikipedia.org/wiki/Perlin_noise. I have tried a number of times to get a firm grasp on all of the details of this algorithm but gave up in the end. The beauty of Flash is that you don’t need to understand how everything works in order to use it to create some stunning effects. I mean do Photoshop users actually understand how the Liquify filter achieves its effects?
Visitor Comments »
Comment by nancy | March 5, 2009 @ 1:32 pm
can’t find the files
Comment by super | March 5, 2009 @ 4:02 pm
Hi, Bravely I chose this as my first attempt at an action script. I got lost at the end and wasn’t sure where to go after all the script was typed in. Could you please let me know the final steps to get me back to the timeline, (I’m using CS4) I think it is a wonderful clip and will keep trying. Thanks in anticipation. Roma
Comment by Roma Thomson | March 7, 2009 @ 3:18 pm
[...] Using the Displacement Filter in Adobe Flash – Written by Lee Brimelow [...]
Pingback by The Monday Roundup | Layers Magazine | March 9, 2009 @ 10:56 am
Can someone verify this actually works.. I’ve been tryin all day and I keep getting error.
tough to see the code on some of it
Comment by Jimmy | March 9, 2009 @ 12:40 pm
I even downloaded the files from this tutorial and copied code exactly.. I got this error
ReferenceError: Error #1069: Property (x=0, y=0) not found on flash.geom.Point and there is no default value.
at water_fla::MainTimeline/water_fla::frame1()
Comment by Jimmy | March 9, 2009 @ 2:37 pm
Is there an example somewhere on the site – what does this do exactly?
Comment by Leslie | March 13, 2009 @ 1:20 am
Hi Super,
To find the files, just click on the link in the second paragraph of the article, and then scroll down to the November/December 2008 issue.
Thanks,
Chris Main
Managing Editor
Layers Magazine
Comment by Chris Main | March 13, 2009 @ 12:22 pm
Hi,
I’d really like to get this to work–it’s an interesting effect, but my script keeps getting errors.I copied it exactly from the tutorial:
var bmd:BitmapData = new BitmapData(540, 334);
var dmf:DisplacementMapFilter = new DisplacementMapFilter (bmd.new Point(0,0).1.2.10.60);var p1:Point = new Point(0, 0);
var p2:Point = new Point(0, 0);
var perlinOffset:Array = [p1, p2];addEventListener(Event.ENTER_FRAME, loop);
function loop(e:Event):void
{
perlinOffset[0].x += 0.2;
perlinOffset[1].y += 0.1;
bmd.perlinNoise(168, 5, 2, 4, true, true, 2, true, perlinOffset);
photo.filters = [dmf];
}And I checked the product help to verify my syntax, which looks okay. Yet, I still get the following errors when I try to run my .swf:
1084: Syntax error: expecting identifier before new.
Comment by Laurel Hale | March 18, 2009 @ 5:28 pm
This is Laurel again. Your feedback well cut off my post, here’s the rest:
The Syntax error: expecting identifier new points to the following line of code:
var dmf:DisplacementMapFilter = new DisplacementMapFilter (bmd.new Point(0,0).1.2.10.60);This is the second error I’m getting:
1084: Syntax error: expecting rightparen before var.
Comment by Laurel Hale | March 18, 2009 @ 5:32 pm
That error points to this line of code:
var p1:Point = new Point(0, 0);
Any ideas?
Comment by Laurel Hale | March 18, 2009 @ 5:33 pm
Hi Laurel,
Change your points for commas between the parenthesis , that should solve the problem…
P.
Comment by patrick | March 22, 2009 @ 8:33 pm
sorry I should have added…
var dmf:DisplacementMapFilter = new DisplacementMapFilter( bmd , new Point(0 , 0) , 1 , 2 , 10 , 60);P.
Comment by patrick | March 22, 2009 @ 8:35 pm
why don’t you at least enlarge the image of showing the script in line 1. It’s too small and I can’t read all of it. The other lines containing the script are enlarged enough. If I can’t get the first line the entire script is a waist of time and whon’t work.
Comment by john | April 11, 2009 @ 7:46 pm
working like a charm,
thanks for the tut
Comment by Bart | May 25, 2009 @ 4:45 am
this ROCKS!… thanks, as usual, for a great tutorial. Took 10 seconds to swap in some other ocean photos and it worked equally well. Great!
Comment by victor | June 29, 2009 @ 8:50 pm
This worked beautifully for me! Thanks so much.
Comment by Monica | July 16, 2009 @ 4:12 pm
Thanks a ton; this is very neat. There’s a lot to explore with filters such as this. I tried this with other waters, and the ripples do look good.
Thing with any graphics API is the need of not having to know how everything works.
Comment by senapati | July 25, 2009 @ 10:19 am
This worked fine for me, thanks for sharing! Very flexible …
Comment by Marotzke | August 8, 2009 @ 8:53 am
photo.filters = (dmf);
Comment by DaveC | August 24, 2009 @ 4:43 pm
I get an error stating 1120: Access of undefined property photo in line 15.
Comment by DaveC | August 24, 2009 @ 4:45 pm
Only wanted to commented how valuable this site is. This coding tutorial worked well for me. However, in the coding example, line 2 does appear to have a syntax error. The parameters that are sent (line 2 in point 6 Create the Displacement Filter), appear in the image to be separated by periods instead of commas. However, when viewing it in the magazine issue(November/December 2008), it is clear that these are commas. I only noticed, because i write in other software languages, and the typical syntax when passing parameters is to separate them by commas. Outside of that, i had no problems with this code. Ran it in Flash CS4 without a hitch. (Okay, well i made some simple mistakes that had to get cleaned up….before it would execute correctly).
Comment by TeeBee | October 3, 2009 @ 11:53 am
great explanation, was able to adapt it to my own situation easily. The only suggestion I would give for those of you who are looking to optimize the CPU load: only apply the filter to a masked, cropped image of the water itself, rather than the entire image, which is covered anyway.
Comment by myeek | January 5, 2010 @ 5:27 pm
if you’re getting “an error stating 1120: Access of undefined property photo in line __”, go back to step 4 and read where it says:
… and give it an Instance Name of photo.
If you want to access properties of objects, they have to be given an instance name. IMO, the tutorial was sloppily written… but once you get the periods to commas and name the object, it works beautifully.
Comment by Dr. Jones | February 25, 2010 @ 1:04 pm
I personally think the water needs to be slowed down a bit. Try changing this line:
bmd.perlinNoise(168, 5, 2, 4, true, true, 2, true, perlinOffset);
to:
bmd.perlinNoise(168, 12, 2.6, 4, true, true, 2, true, perlinOffset);
Comment by Dr. Jones | February 25, 2010 @ 1:10 pm
here the complete code:
note: bmd as variable is reserved in CS4 so I put a $ in front of the variables. (as I usually do) Also note that the movie clip here is “photo_mc” (not photo)
var $bmd:BitmapData = new BitmapData(500,355);
var $dmf:DisplacementMapFilter = new DisplacementMapFilter($bmd,new Point(0,0),1,2,10,60);
// note the commas
var $p1:Point = new Point(0, 0);
var $p2:Point = new Point(0, 0);
var perlinOffset:Array = [$p1, $p2];addEventListener(Event.ENTER_FRAME, loop);
function loop(e:Event):void {
perlinOffset[0].x += 0.2;
perlinOffset[1].y += 0.1;
$bmd.perlinNoise(168, 5, 2, 4, true, true, 2, true, perlinOffset);
photo_mc.filters = [$dmf];
}
Comment by Rainer G | March 3, 2010 @ 6:18 pm
Leave us a comment

- Dragging an Object Between Documents
- TV Scanline Effect
- Trick to the Glossy Effect
- 3D Text
- Changing Type on a Path





Photoshop
Illustrator
Indesign
Dreamweaver
Fireworks
Premiere
Flash
After Effects
Lightroom
Acrobat














