Home > Development > features
Papervision3D: Part 1- Foundation and 3D Object Basics
Papervision3D
Papervision3D is an open-source, MIT licensed 3D engine written in ActionScript 3.0 for Flash. This article will teach you how to set up your first Papervision3D application with the most recent revision as of this writing, Papervision3D 2.0 Alpha, otherwise known as “Great White.” The great barrier for beginners is usually “installing” Papervision3D as they are unfamiliar with subversion, classpaths, and documents classes. The first three sections address these issues with off-site tutorials as that process is not within the scope of this article. So if you’re familiar with the subversion process and setting up an ActionScript 3.0 project, check out Papervision3D at the following link then skip to the “Foundation of Papervision3D” section:
If you don’t know what to do with that link, then continue on reading the links in the first three sections.
Download
First, you need to download Papervision3D using subversion. Follow the instructions at either of these sites:
Classpath
Set up a classpath that points to the Great White “src” directory:
- Using Flash:
- About Setting and Modifying the Classpath
- Using Flex:
- Preparing a Papervision3D Project
Document Class
Create a document class to hold the required ActionScript:
- Using Flash:
- Creating a Document Class with ActionScript 3.0
- Using Flex:
New -> ActionScript Project” - Using FlashDevelop:
- Preparing a Papervision3D Project
Foundation of Papervision3D
I’ll keep the code as simple as I can for those of you new to ActionScript 3.0, but I will assume you have a basic understanding of importing classes, declaring/instantiating variables, and writing/calling methods. If not, O’Reilly’s “Essential ActionScript 3.0” is a great place to start. When I instantiate objects in code snippets, I’ll assume you understand you need to import the relevant classes.
Every Papervision3D application requires four classes: Viewport3D, Scene3D, Camera3D (or alternatives), and BasicRenderEngine (or alternative). Glance at the following typical set up of a Papervision3D project before I dive into a full explanation:
package{
import flash.display.Sprite;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;public class Main extends Sprite{
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
public function Main(){
initPapervision3D();
}
private function initPapervision3D():void{
viewport = new Viewport3D();
addChild(viewport);
scene = new Scene3D();
camera = new Camera3D();
renderer = new BasicRenderEngine();
renderer.renderScene(scene, camera, viewport);
}
}
}
Viewport3D
Think of a Viewport3D as a window to the world of Papervision3D. Windows allow you to see outside, but they serve no other function. You can position a window on the wall or change its width and height, but that’s really about it. The same is true with Viewport3D. You can change the “x”, “y”, “width”, and “height” of the Viewport3D, but its only true functionality is to let you look at the 3d scene inside of it. To use a viewport, create it then add it to the stage.
private var viewport:Viewport3D = new Viewport3D();
addChild(viewport);
For reference, the default parameters of Viewport3D, which you can adjust to your liking, are as follows. I’ll cover interactive, autoClipping, and autoCulling in a future article:
Viewport3D(viewportWidth:Number = 640, viewportHeight:Number = 480,
autoScaleToStage:Boolean = false, interactive:Boolean = false,
autoClipping:Boolean = true, autoCulling:Boolean = true)
Scene3D
To continue with the window metaphor, a Scene3D would hold everything you could see looking through the window: the ground, the sky, and everything in-between. Yet the Scene3D is still just empty 3D space. You have to add the ground, the sky, the trees, etc., by adding 3d objects to your Scene3D. A scene3D is created as follows:
private var scene:Scene3D = new Scene3D();
Camera3D
A window and an outside world are pretty worthless if there’s no one there to witness their beauty. Luckily for you, the developers of Papervision3D created cameras to capture all the action. A Camera3D allows you to set the x, y, and z coordinates from where you want to capture the action. Imagine a first-person shooter or flight simulator. You move your character around and the surrounding area adjusts to your current position. The same idea applies to Camera3D movement: you move the camera and the entire Scene3D adjusts to its current position.
Papervision3D provides three cameras with varying functionalities:
- • Camera3D- requires a target to “look at” and will always “look at” that target regardless of position
- • FreeCamera3D- moves freely through 3D space in every angle and direction. Includes methods such as yaw(), pitch(), and roll() to adjust the camera’s viewing angle as well as moveForward(), moveBackward(); moveLeft(), moveRight(), moveUp(), and moveDown() to adjust the camera’s position based on its viewing angle. For example, if you position the camera looking straight at someone’s face then call moveBackward(), you will move farther and farther back from that person’s face while still looking straight their face. On the other hand, if you position the camera above the person, pitch() the camera to look straight down at their hair, and then call the same moveBackward() method, you will lift the camera higher into the sky while continuing to look at the person’s hair.
- • FrustumCamera3D- moves like FreeCamera3D, but only renders the objects within a field of view, far distance, and near distance that you determine.
BasicRenderEngine
In the world of Papervision3D, you’re God. That means you get to decide when the world exists. Without the BasicRenderEngine class rendering your world, it just won’t exist. So you can start and stop the engine as you please. The BasicRenderEngine renders a Scene3D from the Camera3D position through the Viewport3D that you choose:
private var renderer:BasicRenderEngine = new BasicRenderEngine();
//Usually within an Event.ENTER_FRAME handler so the scene
renders in each frame renderer.renderScene( scene, camera,
viewport );
Even if you have multiple scenes, viewports, or cameras, you still only need one BasicRenderEngine to handle all of the rendering:
//A snippet of multiple scenes, cameras, and viewport handled by one
renderer renderer.renderScene( scene, camera, viewport );
renderer.renderScene( scene2, camera2, viewport2 );
3D Objects
3D Coordinates
Before diving into creating objects, let’s take a look at how objects are positioned in 3D space as opposed to traditional Flash projects.
In Flash, you position an object on the stage based on x:0 and y:0 being in the upper-left corner. Increasing x moves an object to the right and increasing y moves an object down. Conversely, in Papervison3D x:0, y:0, and z:0 are in the center (not the upper-left) of the Scene3D. Since the Camera3D defaults to x:0, y:0, z:-1000 and points at the origin (x:0, y:0, z:0), increasing x moves the object right, increasing y moves the object up, and increasing z moves the object toward the horizon.

Also, remember the amount of movement you will see is based on how close the camera is to the 3d object. The closer the camera the more objects will appear to move. You cannot rely on pixels like you can in a traditional two dimensional Flash project. Consider the following examples based on the default camera position:
- • x = 10; //means 10 units right of Scene3D’s center
- • x = -10; //means 10 units left of Scene3D’s center
- • y = -10; //means 10 units below Scene3D’s center
- • z = -10; //means 10 units closer to the camera from Scene3D’s center (remember Camera3D defaults to z:-1000 so moving from 0 to -10 brings the object closer to -1000.)
If you’re the type of person who must understand how 3D coordinates are possible within in a 2D Flash Player, put on your math hat and read up on quarterions:
http://en.wikipedia.org/wiki/Quarterion
http://www.adobe.com/devnet/flash/articles/3d_classes_03.html
http://www.isner.com/tutorials/quatSpells/quaternion_spells_14.htm
Even if you don’t understand the math involved in those articles, you probably understand that 3D objects are made up groups of 3D coordinates. These 3D coordinates (also known as vertices) form triangles. The triangles form a polygon mesh or, in layman’s terms, a 3D object.
On a side note, Papervision3D uses the Painter’s Algorithm to sort the visibility of those triangles. The Painter’s Algorithm evaluates the sorting quickly (ideal for Flash Player), but can fail if triangles overlap. You typically resolve this issue by creating more segments in your 3D object to give less chance that the triangles overlap.
Plane
I consider Planes to be the most useful 3D objects for most Papervision3D projects, especially if the project is interactive. Oddly enough, a Plane does not technically qualify as a 3D object as it has no depth. A Plane is simply two triangles stuck together to form a rectangle. Remember, the Scene3D holds all of your 3D objects. So to use a plane, create it then add it to the Scene3D.
var plane:Plane = new Plane();
scene.addChild(plane);
A Plane defaults to a WireFrameMaterial (discussed in a later article) with a width of 500 and height of 500. So using the above code will result in a wireframe Plane centered at x:0, y:0, and z:0 with a width and height of 500 facing the camera (assuming the camera is in its default position discussed earlier). When you pass a material with an image inside it, the Plane will default to the width and height of the bitmap of that image. The parameters available for a Plane are as follows:
Plane( material:MaterialObject3D=null, width:Number=0,
height:Number=0, segmentsW:Number=0, segmentsH:Number=0,
initObject:Object=null )
Material, width, and height are pretty self-explanatory. SegmentsW and segmentsH set the number of segments in the width and height of the Plane respectively. Multiple segments help to avoid the distortion of an image when the Plane starts rotating as well as the depth sorting of the triangles as mentioned earlier. The screenshot below demonstrates a Plane with four segmentsW and three segmentsH.
Be wary when creating many Planes as each additional width or height segment you create tacks on two more triangles (essentially forming another rectangle inside the Plane to give the plane more detail). The number of triangles Flash Player can handle varies depending on your application, but generally try and keep the triangle count below 2000.
The last optional parameter, initObject, can store the initial x, y, z, rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, and “extra” parameters. Alternatively, you can directly set the listed properties after instantiating your Plane. A quick example will explain nicely:
var m:WireframeMaterial = new WireframeMaterial();
//width and height
var w:Number = 800;
var h:Number = 800;
//segmentsW and segmentsH
var sW:Number = 1;
var sH:Number = 1;
var initObject:Object = new Object();
initObject.x = 100;
initObject.rotationY = 30;
initObject.scaleZ = 20;
//Option #1 using initObject
var plane:Plane = new Plane(m, w, h, sW, sH, initObject);
scene.addChild(plane);
//Option #2 setting properties directly
var plane:Plane = new Plane(m, w, h, sW, sH, initObject);
plane.x = 100;
plane.rotationY = 30;
plane.scaleZ = 20;
scene.addChild(plane);
One final note about Planes: if you spin a Plane, you’ll notice the plane will disappear once you look at the other side. If you want to have a texture on both sides of the Plane, you will need to enable the “doubleSided” property of your material you pass into your Plane.
material.doubleSided = true;
Sphere
You create a Sphere very similarly to the way you create a Plane:
var sphere:Sphere = new Sphere();
scene.addChild(sphere);
A Sphere’s default parameters closely resemble a Plane’s parameters as well. The Sphere just takes a radius parameter instead of width and height. If you think back to high school, you will probably recall the radius being the distance from the center of the circle to the outer edge. As opposed to the simplicity of width and height of a Plane, the Sphere now uses the radius to calculate the distance between the center and the edges to create groups of three vertices that make groups of triangles that make the Sphere. Pretty neat, huh? The default parameters are as follows:
Sphere( material:MaterialObject3D=null, radius:Number=100,
segmentsW:int=8, segmentsH:int=6,
initObject:Object=null )
For brevity’s sake, a Cone and a Cylinder can be created similarly with the following default parameters:
Cone( material:MaterialObject3D=null, radius:Number=100,
height:Number=100, segmentsW:int=8, segmentsH:int=6,
initObject:Object=null )
Cylinder( material:MaterialObject3D=null, radius:Number=100,
height:Number=100, segmentsW:int=8, segmentsH:int=6,
topRadius:Number=-1,
initObject:Object=null )
Cube
What do you get when you take six Planes and organize them into the shape of a box? A Cube!
By now you should be getting the hang of creating 3D objects, but the Cube throws in a curve ball by requiring a MaterialsList (discussed in a later article). You will probably get the gist of how to use a MaterialsList by reading how to create a Cube:
var frontMaterial:WireframeMaterial = new WireframeMaterial();
var backMaterial:WireframeMaterial = new WireframeMaterial();
var leftMaterial:WireframeMaterial = new WireframeMaterial();
var rightMaterial:WireframeMaterial = new WireframeMaterial();
var topMaterial:WireframeMaterial = new WireframeMaterial();
var bottomMaterial:WireframeMaterial = new WireframeMaterial();
var materialsList:MaterialsList = new MaterialsList();
materialsList.addMaterial(frontMaterial, "front");
materialsList.addMaterial(backMaterial, "back");
materialsList.addMaterial(leftMaterial, "left");
materialsList.addMaterial(rightMaterial, "right");
materialsList.addMaterial(topMaterial, "top");
materialsList.addMaterial(bottomMaterial, "bottom");
var cube:Cube = new Cube(materialsList);
scene.addChild(cube);
The Cube faces forward when rendered meaning, with the camera in the default z:-1000 looking at x:0, y:0, z:0 position, you will be looking directly at the back of the Cube. Without any perspective, it will look exactly like a Plane. You can easily set any of the Cube’s rotation properties to see the full effect (the earlier Cube image was rotated slightly to show perspective). Now let’s cover the default parameters of a cube:
Cube( materials:MaterialsList, width:Number=500, depth:Number=500,
height:Number=500, segmentsS:int=1, segmentsT:int=1, segmentsH:int=1,
insideFaces:int=0, excludeFaces:int=0, initObject:Object=null )
The segments require a little explaining, yet function in the same fashion as Plane’s segments:
- • segmentS - Number of segments sagitally (plane perpendicular to width). Defaults to 1.
- • segmentsT - Number of segments transversally (plane perpendicular to depth). Defaults to segmentsS.
- • segmentsH - Number of segments horizontally (plane perpendicular to height). Defaults to segmentsS.
The insideFaces parameter determines which faces will be rendered on the inside of the Cube. This is useful if you want to have the camera inside of the Cube for the illusion of being trapped in a room. To set the faces you want to include, use the following static public variables of Cube:
- • Cube.NONE
- • Cube.FRONT
- • Cube.BACK
- • Cube.LEFT
- • Cube.RIGHT
- • Cube.TOP
- • Cube.BOTTOM
- • Cube.ALL
Simply create an insideFaces integer that describes which faces you want to see on the inside and pass it as a parameter where appropriate. For example, if you want just the top of the inside of the Cube to be rendered, write the following:
var insideFaces:int = Cube.TOP;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
For just the left, right, and bottom face:
var insideFaces:int = Cube.LEFT + Cube.RIGHT + Cube.BOTTOM;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
For all the faces except the front face:
var insideFaces:int = Cube.ALL - Cube.FRONT;
var cube:Material = new Cube(m, w, d, h, sS, sT, sH, insideFaces);
The next parameter, excludeFaces, works exactly the same way, but excludes the faces you don’t want. Think of it like taking the lid of a shoebox.
Collada
This is where Papervision3D gets really exciting: you create a model in your preferred 3D modeling program (3ds max, Maya, Blender, Swift3D, etc.), export it as a Collada file, and load it using the Papervision3D DAE class. Unfortunately, this topic deserves an article unto itself, but here are a few demos to get you on the right track:
Loading Collada Files into Papervision3D
Testing Kinematics with Papervision3D Collada
DCC Tutorials
Enough Talk, Let’s See Code!
I bet you’re anxious to start tickling the keyboard to see if it laughs out a working Papervision3D project. So let’s make a Cube and spin it using the Cube yaw() and pitch() methods (Don’t fret, I’ll cover the details of yaw, pitch, roll, etc. in future articles):
package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;
[SWF ( width = '640', height = '480', backgroundColor = '#ffffff',
frameRate = '31' ) ]
public class RotatingCubeExample extends Sprite {
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var cube:Cube;
public function RotatingCubeExample(){
initPapervision3D();
createCube();
beginRender();
}
private function initPapervision3D():void{
viewport = new Viewport3D();
addChild(viewport);
scene = new Scene3D();
camera = new Camera3D();
renderer = new BasicRenderEngine();
}
private function createCube():void{
var allM:WireframeMaterial = new WireframeMaterial();
var m:MaterialsList = new MaterialsList();
m.addMaterial(allM, "all");
//width, depth, height
var w:Number = 300;
var d:Number = 500;
var h:Number = 700;
//segments S, T, and H
var sS:int = 2;
var sT:int = 3;
var sH:int = 4;
cube = new Cube(m, w, d, h, sS, sT, sH);
scene.addChild(cube);
}
private function beginRender():void{
//calls the render function every frame
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
//rotates around the vertical axis
cube.yaw(2);
//rotates around the lateral axis
cube.pitch(1);
renderer.renderScene(scene, camera, viewport);
}
}
}Common Mistakes: Help! I Don’t See Anything!
- 1. Did you properly import the Papervision3D classes?
- 2. Did you “addChild()” your viewport?
addChild(viewport); - 3. Did you “scene.addChild()” your 3D Object?
scene.addChild(cube); - 4. Did you render your scene?
renderer.renderScene(scene, camera, viewport);
Just Getting Started
I hope you realize that this article barely touched the tip of the Papervision3D iceberg. The next article will cover the materials (sometimes known as textures) so you can make your 3D objects look nice and pretty.
Thanks
I’d like to thank all of the members of the Papervision3D team, everyone who has ever helped anyone on the Papervision3D mailing list, and the community for making such a wonderful open-source product:
- Core team
- Carlos Ulloa
- John Grden
- Ralph Hauwert
- Tim Knip
- Andy Zupko
- Committer team
- Mr.doob
- De'Angelo Richardson
- Tink
- Seb-Lee Delisle
- Contributors
- Patrick Pietens
- Ron Valstar
Great John,
thanks for this great article. its time for all that stuff packed in a book!
Web goes 3D. Thanks PV3D!
Thank you very much for your tutorial! But where can i get the API documentation of PV2.0(GreatWhite)?Can you give me a URL? http://www.papervision3d.org/docs/as3/is an old version DOC. Thank you! I can't visit the PV3D official blog!
Awesome tutorial! Thanks! Can't wait to see more from you!
@long
There is currently only the following temporary documentation until the official documentation is released by the pv3d team:
http://lostboys.epologee.net/papervision/greatwhite.doc/html/
Hope this helps.
nice article... will visit later for more detailed read n info.
very nice article! a book on this would be great.
Great article John, i would definetly like to see a book on the subject.
thank you, thank you, thank you!! Iv'e been waiting for something like this for ages!
@John Lindquist
Thanks for the docs!
There is also an updated documentation for the Effects branch here :
http://www.flashbookmarks.com/PV3D-Effects-DOC/
Great article !
How about writing an entire book about Papervision ?
Yes a book from O'Reilly it would be great help.
the community needs a book!!
yeah dude, nice wrok, thx
Nice article, however the resources and tutorials about pv3D getting better, I still would love to have a book about papervision3D.
Muchas gracias por el articulo.. pero queremos mas! Y una vez que el libro salga en ingles traduzcanlo al español pls!. Otra vez, muchas gracias
great stuff!!
finally some answers.. hope to see more of that and in that amazing explanatory style!
Book now!
truely John, you and the other members of the pv3d team should get a nobel prize, now if only you could pack it all into a good book....
Great article, it was very helpful. It would be great to see a book on this!!!
Congrats John, really nice and needed article.
I think a book about this would be more than welcome.
Congrats John, really nice and needed article.
I think a book about this would be more than welcome.
I want the book! ;-)
Congrats John. We need this complet book just now. It´s about time would came a book like that.
Please, please, please publish the book!!! :)
Really, the info I find on this issue is so confused and complicated for a designer with average actionscript skills...
You got a buyer here if you publish the book.
Great!
When is the book coming out?!
We really need a book for PV3D. I already know of quite a few people who are interested!
Yes! A book of Pv3D will be so helpfull.
very nice as usual! i cant wait to see something more indepth! keep it up!
book!! book!! book!!
BOOOOOOOOOOOOOOK!!! :)
Book! Book! Book!
Please design the book with some exercises at the end of each chapter, so that it is easier to use as a textbook in game development classes.
Great article for me, thank you very much!
Great article, is there any perspectives on a book coming out?
A book would be very useful
Excellent base article. I've been checking out the tutorials on your site, I'd really love to see this info in a book.
BOOK
A book would be friggin excellentl. In the meantime, maybe some more parts? Very informative!
A book would be great
I think this article is really useful! I would love to have a book on papervision written once the GW version is out of alpha and beta
It would be cool if there was a Papervision 3D book on the market!
I have been hoping for a PV3D book for a while now, it would to see something. I think it would really push the technology forward.
Where can we suggest new books to O'Reilly?
BOOK!BOOK!BOOK!BOOK!
Fantastic. I'm not the most advanced actionscripter and yet your straight forward and detailed writing makes it easy for even me to understand.
Thanks so much! Can't wait for more, I'll be watching.
Great beginning article, can't wait to read more!
A book would be awesome!! Can't wait to see what happens with this.
WRITE A BOOK! I WILL BUY IT!!
this is great stuff. Actually - OREILLY: why don't you do a series of high-qualified online articles available for small cost? Writing a book about this stuff seems to be ok, but in terms of speed, up-to-dateness and delivery to a huge online community who likes to cut-and-paste the code-bits it might just be an alternative...
we need a book....with the source to the shark thing in it.
Great article. Please do more and put me down for a pre-order of any future book!
Are you thinking to publish a book? if so give some nice examples not just for developers but also for designers using papervision. thanks for the wonderfull tutorials
we need urgently a book of papervision3d
So when's the book due?
I'd buy a book on this.
Ditto to all of the above comments on a book for pv3d - WE NEED A BOOK...
Excellent intro to GreatWhite, thanks John!
It was daunting to get started till I stumbled upon this. Hope you can add some more soon! :)
Please print a book for of this. Thanks
Please can we have a Papervision Book, O'Reilly! Go crazy and make it Flex-oriented too.
awesome work!
it´s time to compile all the info in a from-zero-to-hero book!!
thanks John and hope to give thanks soon to OReilly for an excellent book :)
When is book out?!?
Why wait an other day!
Move on O'reilly publish the book we are waiting for...
I want the book now! : )
Cheers form Uruguay
i was just at FITC in toronto and asked Ralph Hauwert about a book... he didn't say much except for maybe. come on book!
Thanks for your article. Hopefully O'Reilly will publish a book on Papervision3D in combination with FLEX (/Flash). Can you have it ready tomorrow??? ;-P
Thanks!