How to Create an HTML5 3D Engine

Dec 18 2010 by Eric Rowell | 19 Comments

How to Create Your Own HTML5 3D Engine

You’re probably aware by now that HTML5 is game-changing. In particular, with the HTML5 canvas, there’s been an outpouring of HTML5 3D JavaScript engines such as three.js released to enhance the rudimentary 2D HTML5 API. After all, 3D graphics is a lot cooler than 2D graphics, right?

It’s probably fair to say that if you were to create a full-blown 3D engine–complete with three dimensional matrix transformations, point objects, plane objects, shading, ray tracing, and other spatial computations–it would be quite difficult.

But what if we wanted to create an optimized, barebones 3D JavaScript engine that supports translations and rotations? How hard would it be?

What if I tell you that we can create our own simple 3D JavaScript engine with just 40 lines of code?

This guide will provide a simple and straightforward JavaScript engine that enables HTML5 3D renderings that can be used in web animation, games, and so forth.

Understanding 3D Projections

Before creating our own 3D engine, we should first understand how the illusion of 3D space is created on a 2D screen. These illusions are called 3D projections. 3D projections map points onto a two-dimensional plane. In our case, the three-dimensional points define an object we wish to render, and the two-dimensional plane is the computer screen.

As you can see in the following image, we can create a three-dimensional projection of a cube on a two-dimensional plane by drawing three irregular quadrilaterals – the top, left, and front quadrilaterals.

3D Projections

Plane Projections with Ellipses

Unfortunately, calculating three-dimensional projections can be quite complex to code. How can we simplify it?

Imagine looking down at a rotating rectangular plane. Its four corners would lie on the outline of a perfect circle, whose radius is equal to half the distance from opposite corners of the rectangle.

Now imagine if we were to tilt the plane in 3D space. What happens? This imaginary circle suddenly becomes an ellipse, whose height is less than its width.

This means that we could create a simple 3D projection by creating planes whose corners reside along the edges of an ellipse.

If we are defining the rotation of the plane with an angle, theta, the 3D projection calculations suddenly become quite simple!

Any point on our three-dimensional plane can be defined with the following two equations which describe a point along the edges of an ellipse:

x = A * cos(theta)
y = B * sin(theta)

where A is half of the ellipse width, and B is half of the ellipse height.

A Simple 3D Engine

If our engine simply creates planes in 3D space, we can build multiple cross-sectional planes that frame a 3D object that we wish to render.

Sample 3D Object Rendering

Plane Projections with Ellipses

Cross-Sectional Planes Diagram

Plane Projections with Ellipses

View demo

This particular 3D shape was created by generating three cross-sectional planes – the top, center, and bottom plane. These imaginary planes provide us with all of the points we need to render the 3D object using the HTML5 Canvas API.

By creating a straightforward function that can generate, translate, and rotate these cross-sectional planes, we have effectively created a simple 3D engine.

Here is the code for our HTML5 3D engine:

// This simple 3D engine was provided by www.Html5CanvasTutorials.com
// for the purpose of creating 3D HTML5 renderings
function Plane(centerX,centerY, planeLength, planeWidth, planeTilt, planeTheta) {
   this.centerX = centerX;
   this.centerY = centerY;
   this.planeLength = planeLength;
   this.planeTheta = planeTheta;
   
   var lastPerspectiveX = null;
   var lastPerspectiveX2 = null;
   var planeNextCornerAngle = 2*Math.asin(planeWidth/planeLength);
   
   this.rotate = function(newTheta) {
   	planeTheta = newTheta - planeNextCornerAngle/2;
   }
   
   this.translate = function(newCenterX, newCenterY) {
   	centerX = newCenterX;
   	centerY = newCenterY;
   }
   
   this.generate = function() {
   	var ovalLength = planeLength;
   	var ovalWidth = ovalLength * planeTilt;
   
   	var perspectiveX = (ovalLength / 2) * Math.cos(planeTheta);
   	var perspectiveY = (ovalWidth / 2) * Math.sin(planeTheta);             
   	var perspectiveX2 = (ovalLength / 2) * Math.cos(planeTheta + planeNextCornerAngle);
   	var perspectiveY2 = (ovalWidth / 2) * Math.sin(planeTheta + planeNextCornerAngle);
   
   	this.topLeftX = (perspectiveX *1) + centerX;
   	this.topLeftY = (perspectiveY * -1) + centerY;
  	this.bottomRightX = (perspectiveX*-1) + centerX;
   	this.bottomRightY = (perspectiveY*1) + centerY
   	this.topRightX = (perspectiveX2 *1) + centerX;
  	this.topRightY = (perspectiveY2 *-1) + centerY;
   	this.bottomLeftX = (perspectiveX2 *-1) + centerX;
   	this.bottomLeftY = (perspectiveY2 *1) + centerY;
   }
 }

This simple 3D engine is completely free to use and modify so long as you keep the commented credits in your code. Enjoy!

Related Content

About the Author

Eric Rowell is the founder and chief editor of www.Html5CanvasTutorials.com and is fascinated with everything related to the web – including business, emerging technologies, online advertising, and social media marketing. You can follow him on Twitter at @ericdrowell.

19 Comments

Auds Velasco

December 18th, 2010

Thanks for sharing Eric! I’m sure we will be seeing a lot of these in the future. They can be also integrated in EDI or have there own IDE in WYSIWYG kind of way.

Cheers! We’ll be following more of your HTML5 Canvas Tutorials!

Paul

December 18th, 2010

Nice example but why does it use so much CPU? I am viewing it in Firefox on a MacBook Pro and the example alone uses 60% CPU?

Tom

December 18th, 2010

Engine?
The engine is html5′ canvas not the code you have written.
Very confusing article.

Eric Rowell

December 19th, 2010

Thanks guys! Tom: This code is a bare-bones 3-d engine because it generates the points needed to draw 3-d projections.

Eric Rowell

December 19th, 2010

Thanks Paul! For this example, I’m using a frame rate of 1 frame per 10 ms (relatively high, but with very smooth frame transitions). If we were to cut the frame rate down to 20 or 30ms, you would see the CPU usage drop dramatically.

HotCustard

December 19th, 2010

Looking forward to seeing some demos of this that really push the limits, what are the potential for games, can any of the current browsers handle it well enough yet?

Young

December 19th, 2010

I’m looking at it in chrome on win7 and getting 15-20% CPU. Nice article, but I dunno how useful it is. This seems like more of a concept exercise than an engine, as Tom said.

alex

December 20th, 2010

@Paul: throw your mbp out the window and get a pc, i have a one year old dualcore pc (everything else than high-end, costed about 750€ at the time) and uses 27-29% of cpu =P
but nevertless it’s still too much i presume, because the applications in the reallife in wich a 3d-engine come to use are fare more complex.

Neitherless: I like the idea that we can use html5+js in (a far) future to visualize 3d-objects without flash or other plugins.

An

December 20th, 2010

Interesting article. I second Tom however – this is not in any way an “engine”.

nicotroia

December 21st, 2010

Maybe in a few years, HTML5.

Brainstorm

December 21st, 2010

What a great article, but this is definitely not an “engine” but a step in the right direction!

Jordan

December 22nd, 2010

Paul: Firefox doesn’t have GPU acceleration yet—unless you enable it in about:flags—so your video card doesn’t get to help process it.

Jordan

December 22nd, 2010

Oops. Was thinking about chrome with the about:flags. My comment is still correct though: no GPU acceleration in firefox until FF4 drops.

GM

December 22nd, 2010

Great article but I could really have use some illustrations regarding the ellipses you refer to perhaps drawn on the 3D objects you have pictured here. Thanks!

Derrick

April 11th, 2011

This is in no way, shape, or form a 3D Engine.

WebGL is a 3D engine. This is doing nothing but some cos/sin trickery to rotate around a y axis.

Rotate it around the X, y, z axis at the same time, then it’ll be “closer” to a 3D engine. ;)

Derek

April 17th, 2011

Derrick: There are lots of JavaScript powered 3d engine up on the web for you to use, not only WebGL. Sometimes you can use JavaScript to simulate 3D effect if a browser does not support WebGL.

Yarus

August 9th, 2011

agree with Derek

here is one example:

http://www.x3daily.com

))

hellen

September 6th, 2011

i agree with GM

Nomisss

September 24th, 2011

For now, HTML 5 sucks! No good standards across browsers, Flash still kicking since it behaves 95% the same way across browsers! Wait for flash player 11, it will blow your mind. Apple sucks too, they just want to make $$ with their apps by not allowing flash on ipdas and iphones… Time to go Steeve!

Leave a Comment

Subscribe to the comments on this article.