Using the DepthOfFieldSprite class

In photography, the depth of field refers to the area in front of the camera that appears sharp and in focus. This effect is quite often used to emphasize a portion of a scene, while de-emphasizing the foreground and background.

When rendering a scene in Away3D, there is no depth of field; the entire scene is in perfect focus. However, the effect can be approximated by using the DepthOfFieldSprite class, which will precalculate a number of increasingly blurry images from the material that is supplied to the DepthOfFieldSprite constructor and store them in a shared cache. One of these images will then be displayed by the sprite at runtime depending on the distance of the DepthOfFieldSprite object to the camera.

package
{
  import away3d.containers.ObjectContainer3D;
  import away3d.core.base.Mesh;
  import away3d.core.utils.Cast;
  import away3d.core.utils.DofCache;
  import away3d.materials.BitmapMaterial;
  import away3d.sprites.DepthOfFieldSprite;

  import flash.display.BitmapData;
  import flash.events.Event;

  public class DepthOfFieldSpriteDemo extends Away3DTemplate
  { 

We embed an image file, which will be used as the base texture for the DepthOfFieldSprite objects.

    [Embed(source="blackdot.png")] 
protected var BlackDot:Class;

The container Mesh into which we will be adding the DepthOfFieldSprite objects is referenced by the container property.

    protected var container:Mesh;

    public function DepthOfFieldSpriteDemo ()
    {
      super();
    }

The DofCache class includes a number of properties that define the appearance of the DepthOfFieldSprite class. These have been defined in the initEngine() function.

    protected override function initEngine():void
    {
      super.initEngine();

The aperture property is used to approximate the effect of a camera's aperture. Larger values for the aperture property increase the depth of field, meaning that DepthOfFieldSprite objects remain relatively sharp over a large area in front of the camera. Smaller values will lead to DepthOfFieldSprite objects appearing sharp within a smaller area.

      DofCache.aperture = 50;

The doflevels property defines how many discreet levels of blurriness will be precalculated and cached for a given bitmap image. One of these cached images will then be displayed by a DepthOfFieldSprite object at runtime, depending on its position relative to the camera. Larger values for the doflevels property result in a smoother transition from one cached image to the next. However, this increased visual quality requires more memory to accommodate the additional cached images and takes more time while the images are precalculated.

      DofCache.doflevels = 32;

The maxblur property defines the maximum blurriness to apply to a DepthOfFieldSprite object. Larger values for the maxblur property will result in more pronounced distinction between those DepthOfFieldSprite objects that are in the depth of field and those that are not.

      DofCache.maxblur = 50;

The focus property defines the distance in front of the camera where DepthOfFieldSprite objects are considered to be in focus.

      DofCache.focus = 2000;

Setting the usedof property to true will allow DepthOfFieldSprite objects to display the depth of field effect. Otherwise, they would behave like a regular Sprite3D object.

      DofCache.usedof = true;
    }

Tip

Each of the properties defined in the DofCache class, with the exception of usedof, has an equivalent property in the Camera3D class. The enableDof() function from the Camera3D class copies these properties from the Camera3D class to the DofCache class, and sets the usedof property to true.

The reason why we have set the values directly on the DofCache class, instead of using those in the Camera3D class, is because the camera's focus will quite often be different to the value used to calculate the depth of field effect. If you remember from Chapter 7, Cameras, setting the camera's focus to 2,000 would decrease the camera's field of view, which would have the undesired effect of providing a very narrow view of the scene.

To get the effect we are after, the values that affect the depth of field effect are set directly on the DofCache class, and the camera is left alone.

In the initScene() function, we create a number of DepthOfFieldSprite objects and add them to the scene.

    protected override function initScene():void
    {
      super.initScene();

Here we define a reference to a BitmapMaterial object that will be supplied to the DepthOfFieldSprite constructor.

Tip

It would be possible to create the DepthOfFieldSprite objects with their own reference to a BitmapMaterial object with the following code:

var sprite: DepthOfFieldSprite = 
  new DepthOfFieldSprite(
  new BitmapMaterial(Cast.bitmap(BlackDot))
)
);

However, doing so increases the amount of time it takes to initialize the application. Supplying a common material object to the DepthOfFieldSprite constructor avoids this issue.

      var blackDotBitmap:BitmapMaterial = 
        new BitmapMaterial(Cast.bitmap(BlackDot));

The container Mesh that will hold the DepthOfFieldSprite objects is created, positioned, and added to the scene.

      container = new Mesh({z: 1000});
      scene.addChild(container);

Now we create the DepthOfFieldSprite objects, and randomly place them in a 1,000 x 1,000 x 1,000 unit area. Because the DepthOfFieldSprite objects are children of the Mesh object created above, their global range along the Z-axis will be from 500 to 1,500, while their ranges on the X and Y axes will both be from -500 to 500.

      var sprite:DepthOfFieldSprite;
      for (var i:int = 0; i < 250; ++i)
      {
        sprite = new DepthOfFieldSprite(blackDotBitmap);
        sprite.x = Math.random() * 1000 - 500;
        sprite.y = Math.random() * 1000 - 500;
        sprite.z = Math.random() * 1000 - 500

        container.addSprite(sprite);
      }

In the onEnterFrame() function, the container is rotated around the Y-axis. This, in turn, rotates the children DepthOfFieldSprite objects, modifying their distance to the camera, and thus showing off the depth of field effect.

    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);
      container.rotationY += 1;
    }
  }
} 

As you can see from the following screenshot, those DepthOfFieldSprite objects that lay within the depth of field are drawn as sharp black dots. As the DepthOfFieldSprite objects move progressively further outside the depth of field, they become increasingly blurred.

Using the DepthOfFieldSprite class
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.25.112