-->

Previous articles summary :

I’d like to illustrate in this post how we can add another essential ingredient to the scene : lighting. Lighting provides a much more realistic rendering of 3D objects and with Papervision3D is very simple to add. The example that I give here shows how lighting is added to a specific material. Papervision3D allows us to specify how the light interacts with the material and provides different qualities of rendering.

First its useful to have a brief summary of the commonly used terms used to describe lighting and shading in 3D graphics.

  • Ambient
    The ambient term in lighting describes non-directional light that is present everywhere in the scene. In the absence of direct light a material will take the colour given by the ambient term.
  • Diffuse
    The diffuse term typically describes how lighting behaves on rough surfaces. When light from a directional light source hits a surface, the light is reflected in many random directions producing a diffuse pattern. For example paper can have a high diffuse term.
  • Specular
    Specular lighting is used to describe shiny objects. Light is typically reflected off these surfaces in a particular direction (as opposed to the diffuse lighting). For example plastics have a high specular term.

Typically objects are made up of a combination of all these lighting characteristics. Now, as I’ve said since the beginning, I’m a beginner in Papervision3D with an OpenGL background and am merely illustrating the progress I’ve personally made over the last few weeks. But, as far as I can tell, the basic shading models available combine ambient lighting with either diffuse or specular and all three is not possible. I’d be very happy if someone could correct me on this… In any case the shading available, produces some beautiful results as we can see in these examples :

You can also find here a useful article on textures, shading and materials which illustrates many techniques possible.

In this post I’d like to show simply how we can add a light source to a scene and implement the four basic types of shading on different materials. These are :

  • Flat shaded
    The colour of a triangle is calculated simply between the face normal and the light source position. Includes diffuse and ambient terms.
  • Gouraud shaded
    Shading is smoothed is smoothed over a surface and is not just dependednt on the normal of the triangle. Uses diffuse and ambient terms.
  • Phong shaded
    Shading is smoothed as for the Goraud, but rather than a diffuse term uses specular and ambiant characteristics.
  • Cell shaded
    Given two colours, the surface is smooth shaded by a specific number of steps.

The code to illustrate these shading models is as follows :

package {
 
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
 
  import org.papervision3d.core.proto.MaterialObject3D;
  import org.papervision3d.lights.PointLight3D;
  import org.papervision3d.materials.shadematerials.CellMaterial;
  import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  import org.papervision3d.materials.shadematerials.GouraudMaterial;
  import org.papervision3d.materials.shadematerials.PhongMaterial;
  import org.papervision3d.objects.DisplayObject3D;
  import org.papervision3d.objects.primitives.Sphere;
  import org.papervision3d.view.BasicView;

  public class Example004 extends BasicView {
 
    private static const ORBITAL_RADIUS:Number = 200;
   
    private var sphere1:Sphere;
    private var sphere2:Sphere;
    private var sphere3:Sphere;
    private var sphere4:Sphere;
    private var sphereGroup:DisplayObject3D;
   
    public function Example004() {
      super(0, 0, true, false);
     
      // set up the stage
      stage.align = StageAlign.TOP_LEFT;
      stage.scaleMode = StageScaleMode.NO_SCALE;

      // Initialise Papervision3D
      init3D();
     
      // Create the 3D objects
      createScene();
     
      // Start rendering the scene
      startRendering();
    }
   
    private function init3D():void {

      // position the camera
      camera.x = -200;
      camera.y =  200;
      camera.z = -500;
    }

    private function createScene():void {

      // Specify a point light source and its location
      var light:PointLight3D = new PointLight3D(true);
      light.x = 400;
      light.y = 1000;
      light.z = -400;

      // Create a new material (flat shaded) and apply it to a sphere
      var flatShadedMaterial:MaterialObject3D = new FlatShadeMaterial(light, 0x6654FF, 0x060433);
      sphere1 = new Sphere(flatShadedMaterial, 50, 10, 10);
      sphere1.x = -ORBITAL_RADIUS;

      // Create a new material (Gouraud shaded) and apply it to a sphere
      var gouraudMaterial:MaterialObject3D = new GouraudMaterial(light, 0x6654FF, 0x060433);
      sphere2 = new Sphere(gouraudMaterial, 50, 10, 10);
      sphere2.x =  ORBITAL_RADIUS;

      // Create a new material (Phong shaded) and apply it to a sphere
      var phongMaterial:MaterialObject3D = new PhongMaterial(light, 0x6654FF, 0x060433, 150);
      sphere3 = new Sphere(phongMaterial, 50, 10, 10);
      sphere3.z = -ORBITAL_RADIUS;

      // Create a new material (cell shaded) and apply it to a sphere
      var cellMaterial:MaterialObject3D = new CellMaterial(light, 0x6654FF, 0x060433, 5);
      sphere4 = new Sphere(cellMaterial, 50, 10, 10);
      sphere4.z =  ORBITAL_RADIUS;

      // Create a 3D object to group the spheres
      sphereGroup = new DisplayObject3D();
      sphereGroup.addChild(sphere1);
      sphereGroup.addChild(sphere2);
      sphereGroup.addChild(sphere3);
        sphereGroup.addChild(sphere4);

      // Add the light and spheres to the scene
      scene.addChild(sphereGroup);
      scene.addChild(light);
    }
   
    override protected function onRenderTick(event:Event=null):void {

      // rotate the spheres
      sphere1.yaw(-8);
      sphere2.yaw(-8);
      sphere3.yaw(-8);
      sphere4.yaw(-8);
     
      // rotate the group of spheres
      sphereGroup.yaw(3);
     
      // call the renderer
      super.onRenderTick(event);
    }

  }
}

This results in four rotating spheres, each one shaded differently and all rotating about the center of the display (click on image to launch animation).


This example uses the same code as in the previous post as a starting block. The initialisation of the 3D is identical : the viewport and the camera position are the same as before. The scene creation is however different to create the four spheres and include a light source.

Adding a light source is very simple in Papervision3D : all we need to do is create a point light source and give it a position.

      // Specify a point light source and its location
      var light:PointLight3D = new PointLight3D(true);
      light.x = 400;
      light.y = 1000;
      light.z = -400;

The value of true in the constructor simply indicates to Papervision3D that we want to artificially render an object representing the light source itself. In this example its not really necessary, but its useful as a debugging tool.

To use the light source we need to create materials that provide shading. The calculation of the colours that we see on the screen are made by these materials rather than the light itself. We can assume that the light source is white light : colours are specified with the materials.

      // Create a new material (flat shaded) and apply it to a sphere
      var flatShadedMaterial:MaterialObject3D = new FlatShadeMaterial(light, 0x6654FF, 0x060433);
      sphere1 = new Sphere(flatShadedMaterial, 50, 10, 10);
      sphere1.x = -ORBITAL_RADIUS;

      // Create a new material (Gouraud shaded) and apply it to a sphere
      var gouraudMaterial:MaterialObject3D = new GouraudMaterial(light, 0x6654FF, 0x060433);
      sphere2 = new Sphere(gouraudMaterial, 50, 10, 10);
      sphere2.x =  ORBITAL_RADIUS;

      // Create a new material (Phong shaded) and apply it to a sphere
      var phongMaterial:MaterialObject3D = new PhongMaterial(light, 0x6654FF, 0x060433, 150);
      sphere3 = new Sphere(phongMaterial, 50, 10, 10);
      sphere3.z = -ORBITAL_RADIUS;

      // Create a new material (cell shaded) and apply it to a sphere
      var cellMaterial:MaterialObject3D = new CellMaterial(light, 0x6654FF, 0x060433, 5);
      sphere4 = new Sphere(cellMaterial, 50, 10, 10);
      sphere4.z =  ORBITAL_RADIUS;

This code creates the four identical spheres positioned on the x-z plane, each one with a different material (being one of the four main shaded material types mentioned above). As you can see, each material takes a light as the first parameter. The two colours are then diffuse and ambient for FlatShaded and Gouraud, specular and ambient for Phong respectively. For the Cell shaded material the two colours are the two extremes which are then split into the n different values. The Phong material takes an additional parameter specifying the level of specular reflection being between 0 and 255 - higher numbers result in more point-like reflections.

Finally I’d like to mention the use of a DisplayObjet3D to group the spheres together :

      // Create a 3D object to group the spheres
      sphereGroup = new DisplayObject3D();
      sphereGroup.addChild(sphere1);
      sphereGroup.addChild(sphere2);
      sphereGroup.addChild(sphere3);
        sphereGroup.addChild(sphere4);

      // Add the light and spheres to the scene
      scene.addChild(sphereGroup);
      scene.addChild(light);

This object acts as a layer that can be manipulated as with any other 3D object. However this manipulation performs an action on all the child objects together as we’ll see when we look at the code for the animation. This object, as well as the light, are then added to the main scene to be rendered.

To animate the scene I wanted all the spheres to rotate about the origin. Rather than calculating the coordinates of each sphere (as I did in my last post), the sphereGroup object allows me to rotate all the spheres together : Papervision3D does all the hard work in calculating their coordinates.

      // rotate the spheres
      sphere1.yaw(-8);
      sphere2.yaw(-8);
      sphere3.yaw(-8);
      sphere4.yaw(-8);
     
      // rotate the group of spheres
      sphereGroup.yaw(3);

As with the previous example, each sphere is individually rotated on its axis. The rotation of all four about the origin now just takes a single line : sphereGroup.yaw(3) : much simpler to code than before !

So there you are ! This is really just a simple example of basic lighting and shading. You’ll find more complex examples on the web, for example including techniques such as bump mapping, to create more realistic scene lighting. Anyway, as always, I hope this has given a few insights into lighting with Papervision3D and please send any comments or suggestions as this article really shows only the tip of the iceberg !

Next article:

10 Responses to “First steps in Papervision3D : Part 4 - lighting and shading”

jokiss said...

Great tutorials. One of the best pv3d tutorial I have ever read. Need more..!

afriend said...

Agreed. Great tutorial, very well explained. Please make more!!!! :)

Roy said...

Agree.. this is the only PV3D tutorial that helps. The wiki is for 1.5 and the examples don’t work.

kilroydx7 said...

Thanks a lot, I didnt have any clue how to get started with PV3D, i dont know why, but I’d been looking for some tutorials and didnt find one that really explained that I need to set a camera, a viewport and a scene before doing anything else in PV3D, once being aware of that everything is much easier.

maro said...

but….for flash only(not flex)
how to put a light with shadow’s object and cast shadow?
thanks

tartiflop said...

This tutorial’s aim isn’t to explain casting shadows… its only for simple lighting and shading. If you want to get started on this then I’d recommend looking at Andy Zupko’s blog on shadow casting.

brianFox said...

i bought you a couple of beers, wish it were more, but i’d hear the old lady yelling about spending so much money over the holidays.
these tutorials have finally brought everything into focus for me. thanks.

brownman said...

yaaaaaaaaahoooooooooooo :)

brownman said...

oops i did wanted to write it after lesson 5..
because of the jumpy feeling..

thanks !

[...] you have not worked with Phong Shaders yet, I recommend you check out Tartiflop’s tutorial. This covers most shading methods in PV3D, and will give you some grounding to experiment on your [...]

-->