One PaperKing to Rule Them All
The Papervision3D guys are running a nice little contest for the title of “PaperKing3D”. I thought this would be good chance to show an example of some of the recent stuff I’ve been working on. Here’s the demo, and here’s the source code.
Read on for more detail about the code and some of the inspiration.
First a word on the inspiration. I come from a photography background so it shouldn’t come as much surprise that in my design work I tend to think of things like a photographer — using space, composition, and cameras. This is why engines such as Papervision3D are exciting to me; they give me a chance to combine all of my interests in photography, graphic design, and programming into one medium. There are also a lot of parallels between programming and photography, namely that they are both fairly technical and require a bit of pre-visualization. The majority of your effort is spent constructing an implementation towards that imaginary goal — manipulating code very much like manipulating light to achieve a photograph. So with those similarities in mind I wanted to highlight the use of light in this demo. I also began thinking of the physical design of cameras themselves and some of the old classics. It almost seems silly that the machine designed to create art becomes a work of art itself, but this happens with code as well. Things of such complexity can be studied and studied creating their own following. So looking around flickr for old cameras I came across a picture of this little gem…

One of Walter Dorwin Teague’s modernist designs for the “Gift No. 1A” during his time at Kodak (a Western New York icon btw). Quite the sporty little accessory to have around your neck in the early 1930’s. This became a good place to start laying out the scene’s look and structure.
The Code
More than likely you’re visiting this page and could probably care less about any background inspiration and want to see how the example works. As I mentioned before, the source code is available so I won’t go through everything, but just highlight some of the more trickier issues.
In a nutshell this scene is just a collada model that I exported from Maya and baked textures onto. Papervision is a fantastic 3D engine but since we are working in a browser with Flash we are very limited by what a software renderer can do. With that in mind we have to create a very low-poly mesh and reduce our triangles count as much as we can. (Pop quiz, what do 3D modeling and type design have in common? Both require that you achieve the maximum expression of a shape with a minimum amount of points.) But, and this is a big but, when modeling the ground and wall planes you’ll be tempted to get rid of all the extra polygons — this is a mistake. We need those extra polys to hold the texture position correctly. [If we didn’t we could turn on precision for the material, but that would slow everything up.] So you may want to do some experimenting with count versus performance, I found a 10 x 10 plane to be a satisfactory compromise.
Another concern in the modeling stage is how the objects are grouped. Before you export your model be sure to combine the meshes you want as one texture and give it an easy name to remember (simply grouping the objects is not enough). This will make it more convenient when assigning your model parts to separate viewport layers later on. Apply a simple lambert shader to the objects and change the shaders name, it’ll be quicker to locate when you’re searching through the collada xml later.
Model, light, render, bake, and export your textures as you normally would. Make sure your models have been UV mapped and keep in mind your textures should be 512 x 512 (1024 if you really need it) for performance reasons.
When loading the images as materials you’ll need to replace the shader name that it’s given within the collada xml. Doing a search for “instance_material” will give you something that looks like:
<instance_material symbol="lambert1SG" target="#myShaderName"/>
You’ll be looking for the symbol name that we’ll add to the material list so we can swap in our texture:
//create material list var matList:MaterialsList = new MaterialsList(); //convert to a bitmap var textureBitmap:Bitmap = new myTexture() as Bitmap; //now swap our bitmap material into the shader name that we found in the collada matList.addMaterial(new BitmapMaterial(textureBitmap.bitmapData), "lambert1SG"); //once you have your collada loaded then apply the material list model.materials = matList;
Now we still may get flickering polys with the model and the ground plane. This is a z-sorting issue that we can fix by using Papervision’s ViewportLayers. Andy Zupko has a much better explanation of using them with effects so I won’t repeat that, I’ll just show the relevant parts in my code:
viewport.getChildLayer(model.getChildByName("floor", true)); var wordLayer:ViewportLayer = viewport.getChildLayer(model.getChildByName("words", true)); wordLayer.alpha = 0.8;
The names “floor” and “words” are the names I gave the objects when I combined their meshes earlier. Since in my demo I wanted to simulate caustics I needed to make the model a little transparent. Since you can’t adjust the alpha of a BitmapMaterial I added the model to a separate viewport layer and adjusted it’s transparency there. And since both the floor and the words are being rendered on separate layers we can eliminate the “z-fighting”.
Well I hope that helps someone. The Papervision team are doing a fantastic job but you’ll need to help yourself as well. It’s up to careful modeling and texture optimization that will give you the biggest performance gains.
