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 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:

  • 3D rendering of the HTML5 logo
  • 3D sky panorama
  • Cool 3D Tetris game
  • Terrain simulation
  • 3D geometric shapes

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


IEBlog