Galactic: Building a 3D Solar System with HTML5

Last November, we released the Galactic test drive alongside IE9 Platform Preview 7. This test drive is a 3D simulation of our solar system and depicts planets orbiting around the sun. You can press the “V” key to toggle between a close up view centered on the sun and a zoomed out view showing more of the entire scene.

When I set out to build Galactic, I knew that I wanted to use HTML5 Canvas to render my scene in 3D, but I wasn’t quite sure how to go about it. After skimming a handful of 3D math texts, I realized it would take more than a weekend to learn all the concepts I’d need to build a 3D engine from scratch. So instead, I searched the Web and found several 3D JavaScript libraries.

After investigating a few of these libraries, I decided to use Mr. Doob’s excellent three.js library. This library supports a variety of browsers and rendering targets (including HTML5 Canvas), and lets you import 3D models from editors such as Blender. I played around with some of the samples to wrap my head around the library, and was soon ready to start building the Galactic demo. Cool!

My first step was to setup my scene. I knew the backdrop to the solar system should contain stars and look ‘cosmic’, so I decided to add a skybox to simulate the sky.

Two walls of the skybox (no textures applied)

// front wall

walls.push(new Wall(5000, 3000, new THREE.Vector3(0, 0, -3000), new THREE.Vector3(0, 0, 0), Materials.Space.Material));

// back wall

walls.push(new Wall(5000, 3000, new THREE.Vector3(0, 0, 1000), new THREE.Vector3(0, 180 * Math.PI / 180, 0), Materials.Space.Material));

// left wall

walls.push(new Wall(4500, 4000, new THREE.Vector3(-3000, 0, -1000), new THREE.Vector3(0, 90 * Math.PI / 180, 0), Materials.Space.Material));

// right wall

walls.push(new Wall(4500, 4000, new THREE.Vector3(3000, 0, -1000), new THREE.Vector3(0, -90 * Math.PI / 180, 0), Materials.Space.Material));

Two walls of the skybox (textures applied) Second, I needed to find a cool image for my space material, and what better place to find photos of space than NASA? So I spent a while browsing the NASA Image Gallery and found a couple of great photos. I applied these images to the scene, which created the desired effect, shown to the right.

Third, I needed to draw the sun. I wanted it to appear fiery and glowing, so I decided to render it as a series of 2D planes, positioned on top of each other in 3D space. Back at NASA, I found a good sun image and inserted it into my code:

Sun rendered as a series of planes

// the sun

for (var i = 0; i < 15; i++) {

var ring = new THREE.Mesh(new Plane(200, 200, 1, 1), Materials.Ring1.Material);

ring.position = gGalaxy.CenterPoint;

ring.rotation = new THREE.Vector3(i * 15, i * 15, 0);

ring.doubleSided = true;

AddToLayer(ring, 3);

}

Now it was time to add the planets. I decided to implement them as simple 3D spheres. I created meshes for each planet using more images from NASA, and added them to my scene. I then setup a simple elliptical motion to make each planet ‘orbit’ the sun.

Planets orbiting the sun

var mesh = new THREE.Mesh(new Sphere(radius, _detail.x, _detail.y, true), material);

The solar system scene was really starting to come together now, but I felt the planets could use a glow effect. To accomplish this, I used a similar technique as with the sun to render a series of semitransparent ‘rings’ around each planet:

Glow effect around planet Earth

// earth glow

for (var i = 0; i < 4; i++) {

var ring = new THREE.Mesh(new Plane(60, 60, 1, 1), Materials.EarthGlow.Material);

ring.position.x = gEarth.Position.x + i * 10;

ring.position.y = gEarth.Position.y + i * 10;

ring.position.z = gEarth.Position.z + i * 10;

ring.rotation = new THREE.Vector3(i * 20, i * 20, i * 20);

ring.doubleSided = true;

ring.i = i;

gEarthGlow.push(ring);

AddToLayer(ring, 5);

}

A shooting star As a final touch, I added shooting stars which randomly shoot across the sky ever few seconds. The star was created using a plane and animating it across the skybox.

Finally, I set up a secondary camera view and rendered it in the lower right corner of the window. I wanted users to see the scene close up and zoomed out, simultaneously.

The final 3D Solar System scene rendered in IE9

And I was done! The simulation may not be scientifically accurate, but I figured it wasn’t bad for a weekend of experimenting.

There are many interesting 3D visualizations you can create with the techniques and library I used for Galactic. Here are a few links to some other great 3D experiments developers have created using HTML5 canvas:

Internet Explorer 9 provides fully hardware accelerated rendering to the entire Web platform. This helps existing sites run faster and also enables fluid new experiences like these 3D simulations that developers can create today. I hope this write-up showed you how simple it is to get started having fun with 3D graphics and HTML5 Canvas. Special thanks to Mr. Doob and the other developers who are showing the world what’s possible with HTML5.

—Seth McLaughlin, Program Manager, Internet Explorer Performance