User Demos - 3D .OBJ Viewer (by Toxicgonzo)

Canvas Rasterization

I wrote an HTML5 canvas app that loads a 3D .OBJ file and displays it in real-time. This particular app takes Blender's monkey model and rotates it. It also displays how many FPS in the upper left corner.

I tested this app in 3 different browsers:
1st choice - Opera ~40 fps
2nd choice - Chrome ~30fps
3rd choice - Firefox ~15fps

This example requires a browser that supports the HTML5 <canvas> feature.

Developer Notes

I had never really thought about it, but though the internet had a wide assortment of media - videos, music, games, it
was distinctly lacking in 3d applications.  Sure, there was VRML and others, but they never really took off.  If you asked me back
then, I would have dismissed it as being that most web users didn't have the horsepower to run 3d applications in their
browsers.  Today, this is not true.

My first stab at 3d web development began with Google's O3D [http://code.google.com/apis/o3d/docs/samplesdirectory.html].  O3D is
a good development environment for 3d - in fact, I was surprised by how easy it was compared to OpenGL.  For example, entire 3d models
could be loaded using a single command, while as with OpenGL you would have had to write your own low-level model loader.
Not to mention, Google made integration with Sketchup easy.  Eventually, though, for a number of reasons I backed of O3D.  Don't get me
wrong, it's pretty good, but one major put off was that it was still in development and not widely adopted.

It was around this time I happened to stumble upon HTML5's Canvas element.  I could see the canvas element becoming more widely
adopted than O3D.  I started experimenting with it, just for the fun of it, with no goal in mind.  Once I found out it could draw polygons, I had
a crazy idea. I wondered: "Is it possible to use a canvas to do 3d?" And so it began.  I never really thought it would work out - I always
thought the 3D math would be beyond my scope.  The truth is that it's actually not that difficult - its a matter of understanding matrix math.
I got a lot of help from these books:


http://www.amazon.com/Primer-Graphics-Development-Wordware-Library/dp/1556229119/ref=sr_1_1?ie=UTF8&s=books&qid=1269144813&sr=8-1


http://www.amazon.com/Real-Time-Rendering-Third-Tomas-Akenine-Moller/dp/1568814240/ref=sr_1_1?ie=UTF8&s=books&qid=1269144821&sr=8-1

Here's the basics of how my app works:
1.  A 3d .OBJ object is stored as a string in the javascript file
2.  The .OBJ string is decoded to hold information about vertex position and which vertices form the polygons
3.  Every polygon is assigned a random color
4.  Matrix multiplication happens:  Convert object from model space -> camera space -> clip space -> screen space
5.  Z-sort the polygons based on the polygon's centroid
6.  Draw the polygons from back to front

I haven't spent a lot of time developing, so there are a lot of areas of improvement [i.e. backface culling].  However, it's also
important to realize that this is software rendering we are talking about which means there are a lot of limitations. 
For example, texturing is too computationally expensive to be done in real time.  If the canvas gradient object were a little
more versatile, then Gouraud shading could be done instead of Flat shading.

I tested this app on 3 different browsers - Firefox, Chrome and Opera.  Firefox ~15 fps, Chrome ~30fps, and Opera ~40fps.
The monkey model I tested this on is a relatively simple 3d model, and yet, I did not achieve 60fps like I hoped to.  However,
I didn't use any optimization tricks like backface culling. I can see future browsers being beefed up to meet the demands of
intensive canvas applications.

The future of 3d web applications probably lies with WebGL which is still being developed by the Khronos group [http://www.khronos.org/webgl/].
I do, however, like using HTML5's canvas because unlike WebGL, canvas will be able to run on any HTML5 enabled browser [software rendered]
while as WebGL only runs on computers with hardware acceleration.  Also, I had trouble learning the opengl shading language (which is what webgl
is based off of).  Finally, writing a renderer from scratch gives you the advantage of understanding how everything works.

Software rendering in canvas is good for 3d apps which are not too complicated.  A rough benchmark I did seemed to show I could draw on the
order of hundreds of triangles to a 640x480 canvas while maintaining a descent framerate.  It's not much, but I could see that being enough
for a simplistic game.

And that's what I plan to do if I have the time - make a simplistic game.  I'm thinking something like a 3d platformer.