Real 3D Rendering right inside the browser

So far, you’ve always needed a plugin to even display dynamic 2D graphics, never mind 3D. So here‘s a 3D engine that works right inside your browser, no plugin required.

OK, first for all of you impatient guys, the controls:

  • Arrow Keys: Turn/Walk
  • PageUp/PageDown: Fly

Flying only works when you’re outside the map, on the map you’ll get put onto the nearest surface automatically.

Now a bit of background info:
This is a demo program for the Canvas element, which is right now being formulated as a standard over at
WHATWG.
The Canvas element is a 2D Bitmap surface to which you can draw to directly from JavaScript. So far, you couldn’t
do graphics in Javascript, aside from dynamically loading different bitmaps from the server. The Canvas element closes
that gap. Now you can actually draw arbitrary shapes, without loading anything from the Server.
For that purpose, the Canvas element provides an API that allows you to draw vector shapes and bitmaps.

The target for Canvas is to not only provide a 2D API, but also one for 3D based on OpenGLes. Sadly, this API
hasn’t yet arrived, and it looks like it will take some time until browsers support it, but the 2D API is here and it’s
working just fine in anything but InternetExplorer, and even for that Google provides wrapper code free of charge
(note however that this wrapper code isn’t being used here, so you’ll need either Firefox 2+ or Opera 9+, Safari hasn’t
been tested). So I decided to write a little 3D Renderer myself. It’s not complex, it’s not finished, but what the hell:
it works. While this isn’t the first attempt to do this
(Canvascape comes to mind),
it is as far as I know the first one to try real 3D instead of Doom-style pseudo 3D. In fact, this demo loads a standard
Alias Wavefront OBJ file, and builds the model from the triangles it finds in there.

So what does this demo do? Well, basically this:

  • Load a model
  • Set up controls to modify a view object
  • Find the nearest triangle below the player
  • Move the player down to that triangle
  • Rotate the model
  • Clip it against Z=0 so you only render what’s in front of you
  • Split partially visible triangles against Z=0
  • Project all vertices, so that they get smaller the farther away they are
  • Draw them, with the distance dictating the color

It’s a bit more complex, but these are the important parts.

So what do I want to do with this? Well, eventually it should becomes a little racing game. Remember ReVolt?
Something like that and from the performance I get so far, it seems possible.
Which brings me to the needed optimizations:
I’ve got absolutely no idea why, but it seems like all Canvas implementations do pixel based clipping against
the drawing window, instead of shape-based clipping… essentially that means that drawing a 1000×1000 pixel
shape, it takes 100 times as long as drawing a 100×100 pixel shape, even when the Canvas is only 20×20 pixels
in size.
Then the game needs a BSP tree because JavaScript is too slow to calculate visibility for every triangle in
realtime… so there has to be a structure that dictates that from position 1,1,1 faces 2,5,8,10 are visible, while
from position 5,6,12 faces 3,15,33,110 are visible.
Then we need a real colission detection for a meaningfull game and support for sprites.
There will probably be a 1000 other things to do, but that’s what I have in mind now.
Oh, and forget about textures… it’s just not possible at descent speed.

Notes. The code is copyrighted Hans Schmucker and licensed und the GPL v2.5

5 thoughts on “Real 3D Rendering right inside the browser”

  1. I’m a 3d designer and I’ve done a lot of development work using low-polygon, low requirement rendering techniques. After looking at what you’ve developed, I was wondering how you stand on providing these things:

    – Different colors for different faces or objects
    – Control of lines on or off (Or always off)
    – Control background color
    – Navigation of a space with collision detection
    – 2d or 3d vector sprites

    I’ve seen some of these things done in the maze/shooter uses of canvas.

    Thanks

  2. Herr Schmucker,

    I’ve been working with Anthony on this, and I’ve added color functionality, but one thing we’d like to see fixed is that there are small gaps between the triangles, and I can’t figure out how to fix it because I don’t have enough 3d knowledge. Here’s a link to the updated code:
    http://64.169.2.120/deer/easterBunny002Rotated/
    (temp URL to my desktop)

    Also, collision detection would be great.
    The js has been put in it’s own file, as well as some other minor changes, but the rendering engine is the same. It seems to die at about 1000 triangles/model.

    Good work on this. It’s really cool, and we’re waiting for updates!

    –Jason

  3. That’s awesome! I did a 3-D renderer in <canvas> at almost exactly the same time — http://lists.canonical.org/pipermail/kragen-hacks/2007-February/000448.html and http://pobox.com/~kragen/sw/torus.html — but your ability to load external files really rocks!

    Jason P., the problem with the gaps between the polygons is a defect in the way browsers implement <canvas>. Old versions of Ghostview will do the same thing with the standard tiger test image if you turn on “antialiasing”. Hopefully we can get this fixed in future <canvas> implementations. Maybe it’s already fixed in 3.

Leave a Reply

Your email address will not be published. Required fields are marked *

*