Additional renderers

All the applications shown in this book have made use of the default renderer. Away3D includes three different types of renderers, each returned by static properties in the Render class from the away3d.core.render package.

The default renderer is created by the BASIC property. The other two renderers, created by the CORRECT_Z_ORDER and INTERSECTING_OBJECTS properties, are quadtree renderers, which are more advanced than the default BASIC renderer.

The CORRECT_Z_ORDER renderer uses a more sophisticated algorithm for sorting 3D objects in the scene, which can solve some (but not all) z-sorting issues that arise when using the default renderer. The renderer returned by the INTERSECTING_OBJECTS property goes one step further by additionally splitting intersecting triangles.

Using these renderers is quite simple. First the Renderer class is imported.

import away3d.core.render.Renderer;

Then in the initEngine() function we pass the object returned from the Renderer CORRECT_Z_ORDER or INTERSECTING_OBJECTS properties to the View3D constructor via the renderer init object parameter.

protected function initEngine():void
{
  scene = new Scene3D();
  camera = new Camera3D();
  view = new View3D(
    {
      renderer: Renderer.INTERSECTING_OBJECTS
    }
  );
  
  scene = view.scene;
  camera = view.camera;

  addChild(view);

  view.x = stage.stageWidth / 2;
  view.y = stage.stageHeight / 2;
}

The active renderer can also be changed at runtime by modifying the View3D renderer property.

view.renderer = Renderer.CORRECT_Z_ORDER;

The RenderersDemo application allows you to change between the three renderers at runtime by pressing 1, 2, or 3 on the keyboard, providing an opportunity to compare how they deal with intersecting 3D objects.

package 
{
  import away3d.cameras.Camera3D;
  import away3d.containers.Scene3D;
  import away3d.containers.View3D;
  import away3d.core.render.Renderer;
  import away3d.materials.WireColorMaterial;
  import away3d.primitives.Cube;
  import away3d.primitives.Triangle;
  
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.text.TextField;
  
  public class RenderersDemo extends Away3DTemplate
  {
    private var triangle:Triangle;
    private var box:Cube;
    
    public function RenderersDemo():void
    {
      super();
    }
    
    protected override function initScene():void
    {
       super.initScene();
       triangle = new Triangle(
        {
          edge: 150,
          bothsides: true,
          yUp: false,
          material: new WireColorMaterial(0x224488),
          z: 500
        }
      );
      scene.addChild(triangle);
      
      box = new Cube(
        {
          z: 500,
          width: 50,
          height: 75,
          depth: 50,
          material: new WireColorMaterial(0x228844)
        }
      );
      scene.addChild(box);
    }
    
    protected override function initListeners():void
    {
      super.initListeners();
      stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
    }
    
    protected override function initUI():void
    {
      super.initUI();
      var text:TextField = new TextField();
      text.text = "Press 1 to enbale the BASIC renderer.
" +
        "Press 2 to enable the CORRECT_Z_ORDER renderer.
" +
        "Press 3 to enable the INTERSECTING_OBJECTS renderer.
" + 
        "Press 4 to make the box transparent.
" +
        "Press 5 to make the box opaque.";
      text.x = 10;
      text.y = 10;
      text.width = 300;
      this.addChild(text);
    }
    
    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);
      triangle.rotationY += 3;
      box.rotationY -= 1;
    }
    
    protected function onKeyUp(event:KeyboardEvent):void
    {
      switch (event.keyCode)
      {
        case 49:
          view.renderer = Renderer.BASIC;
          break;
        case 50:
          view.renderer = Renderer.CORRECT_Z_ORDER;
          break;
        case 51:
          view.renderer = Renderer.INTERSECTING_OBJECTS;
          break;
        case 52:
          (box.material as WireColorMaterial).alpha = 0.5;
          break;
        case 53:
          (box.material as WireColorMaterial).alpha = 1;
          break;
      }
    }
  }
}

In the following image, you can see the difference that the INTERSECTING_OBJECTS renderer makes. With the default BASIC renderer, shown on the left, the triangle appears to be behind the cube, despite the fact that the two 3D objects are actually intersecting. The INTERSECTING_OBJECTS renderer, shown on the right, will split the individual triangle faces that make up the 3D objects in order to correctly render the scene.

Additional renderers

The scene created by the RenderersDemo application is trivial, involving only a single cube primitive and a single triangle primitive. In this case, switching between the three renderers probably won't have a great deal of impact on the performance of the application. But what happens in a more complex scene?

The RenderersPerformanceDemo application creates a number of spheres that bounce around inside an invisible box. Just like the RenderersDemo application, you can switch between the three renderers at runtime.

package
{
  import away3d.core.render.Renderer;
  import away3d.primitives.Sphere;
  import flash.geom.Vector3D;

  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.text.TextField;

  public class RenderersPerformanceDemo extends Away3DTemplate
  {
    protected static const SPEED:Number = 0.5;
    protected static const BOXSIZE:Number = 20;
    protected static const NUMBERSPHERS:Number = 10;
    protected var spheres:Vector.<Sphere> = new Vector.<Sphere>();
    protected var directions:Vector.<Vector3D> = new Vector.<Vector3D>();

    public function RenderersPerformanceDemo()
    {
      super();
    }

    protected override function initScene():void
    {
      super.initScene();
      this.camera.z = 50;
      for (var i:int = 0; i < NUMBERSPHERS; ++i)
      {
        var sphere:Sphere = new Sphere(
          {
            x: Math.random() * BOXSIZE - BOXSIZE/2,
            y: Math.random() * BOXSIZE - BOXSIZE/2,
            z: Math.random() * BOXSIZE - BOXSIZE/2,
            radius: 2
          }
        );
        spheres.push(sphere);
        this.scene.addChild(sphere);

        directions.push(new Vector3D(
          Math.random() - 0.5,
          Math.random() - 0.5,
          Math.random() - 0.5)
        );
        directions[i].normalize();
        directions[i].scaleBy(SPEED);
      }
    }
    protected override function initListeners():void
    {
      super.initListeners();
      stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
      stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
    }

    protected override function initUI():void
    {
      super.initUI();
      var text:TextField = new TextField();
      text.text = "Press 1 to enbale the BASIC renderer.
" +
        "Press 2 to enable the CORRECT_Z_ORDER renderer.
" +
        "Press 3 to enable the INTERSECTING_OBJECTS renderer.";
      text.x = 10;
      text.y = 10;
      text.width = 300;
      this.addChild(text);
    }

    protected function onKeyUp(event:KeyboardEvent):void
    {
      switch (event.keyCode)
      {
        case 49:
          view.renderer = Renderer.BASIC;
          break;
        case 50:
          view.renderer = Renderer.CORRECT_Z_ORDER;
          break;
        case 51:
          view.renderer = Renderer.INTERSECTING_OBJECTS;
          break;
      }
    }

    protected override function onEnterFrame(event:Event):void
    {
      super.onEnterFrame(event);
      for (var i:int = 0; i < 10; ++i)
      {
        var newPosition:Vector3D = new Vector3D();
        newPosition = spheres[i].position.add(directions[i]);

        for each (var property:String in ["x", "y", "z"])
        {
          if (newPosition[property] < -BOXSIZE/2)
          {
            newPosition[property] = -BOXSIZE/2;
            directions[i][property] *= -1;	
          }

          if (newPosition[property] > BOXSIZE/2)
          {
            newPosition[property] = BOXSIZE/2;
            directions[i][property] *= -1;	
          }
        }

        spheres[i].position = newPosition;
      }
    }
  }
}

A scene made up of ten spheres is still quite simple by most standards, but note what happens when you switch to the CORRECT_Z_ORDER or INTERSECTING_OBJECTS renderers from the default BASIC renderer. Chances are, the application went from being smooth and fluid to quite jerky. And that's if it doesn't just throw an error about the script time out.

Additional renderers

The RenderersPerformanceDemo application demonstrates the performance limitations of the more advanced renderers. For all but the most simple of scenes it is generally best to try and correct the sorting order of 3D objects manually in order to maintain a reasonable frame rate.

..................Content has been hidden....................

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