Depth of Field in flash (DOF)
For my latest game I wanted to simulate DOF in flash. In flash we can apply filters to objects and flash provides a blur filter, this is the base of the work. What we need is a mechanism to coordinate the depths of the objects.
First We build a class that manages everything about DOF. This class needs an array which holds references to all the objects we want to use with DOF. We build a virtual space with the depths of 1 where 0 is the position of the camera and 1 is the point most faraway from the camera. Our class has a function addObject which takes the display object and a depths in our virtual space. Next our class has got a property maxBlur that defines how strong the maximum blur effect will be. And of course there is a property focus which defines the current focus.
In my game I needed the effect animated, so I added a main function which manipulates the focus and recalculates the blur effect for each object.
- package at.lueftenegger.dof {
- import at.lueftenegger.dof.operator.Operator;
- import flash.display.DisplayObject;
- import flash.filters.BlurFilter;
- public class Dof{
- public var maxBlur:Number = 5;
- private var _focus:Number = 0; // 0 -> 1
- private var last_focus:Number;
- public var operator:Operator;
- public function Dof(){
- objects = new Array();
- operator = new Operator();
- }
- protected var objects:Array;
- public function set focus(value:Number):void {
- _focus = value;
- render();
- }
- public function addLayer( object:DisplayObject, position:Number ):void {
- if (position < 0) position = 0;
- if (position > 1) position = 1;
- var l:Layer = new Layer();
- l.dispObj = object;
- l.position = position;
- objects.push(l);
- }
- public function main():void {
- _focus = operator.giveFocusValue();
- if(_focus == last_focus) return;
- render();
- last_focus = _focus;
- }
- private function render():void {
- for ( var i:String in objects) {
- var h:Number = ( (objects[i].position - _focus) < 0 ) ? -(objects[i].position - _focus) : (objects[i].position - _focus);
- var blur:Number = h * maxBlur;
- var filter:BlurFilter = new BlurFilter( blur, blur, 1 );
- var filterss:Array = [];
- filterss.push(filter);
- objects[i].dispObj.filters = filterss;
- }
- }
- }
- }
- package at.lueftenegger.dof{
- import flash.display.DisplayObject;
- public class Layer{
- public var position:Number;
- public var dispObj:DisplayObject;
- }
- }
- package at.lueftenegger.dof.operator{
- public class Operator{
- public function Operator(speed:Number = 0.15){
- }
- public function giveFocusValue():Number {
- return 0.5;
- }
- }
- }
- package at.lueftenegger.dof.operator{
- public class Sinus extends Operator{
- private var speed:Number;
- private var run:Number = 0;
- public function Sinus(speed:Number = 0.15){
- this.speed = speed;
- }
- override public function giveFocusValue():Number {
- run += speed;
- return 0.5 + Math.sin(run) * 0.5;
- }
- }
- }
How to use it
- Create a new FLA file.
- Put some MovieClips on screen and give them names.
- Add the following script.
- var dof:Dof = new Dof();
- dof.operator = new Sinus(0.1);
- dof.maxBlur = 10;
- dof.addLayer( getChildByName("object1"),0);
- dof.addLayer( getChildByName("object2"),0.2);
- dof.addLayer( getChildByName("object3"),0.4);
- dof.addLayer( getChildByName("object4"),0.6);
- dof.addLayer( getChildByName("object5"),0.8);
- dof.focus = 0.4;
- 2 Comments



update
Hi!
I have updated the class. Some improvements, inlining math functions. Usage of Object replaced with the Layer class. State pattern added to control the movement of the focus.
michael
Blur Filter
http://www.as3tutorial.com/tutorial/creating_blur_function_using_as3/13/ , Simple using Blur Filters with function.