Wrapping Your Head Around Canvas: Part 5

The WebGL portion of Canvas isn’t so much a fringe as an add on to Canvas. Since we’ve been working in the 2D API over the course of this series, we can now move on to working with 3D.

Much like it’s 2D counterpart, WebGL portions of the Canvas API are still in their infancy ,in my opinion, which leaves a lot of room for improvement. Then again what technology really ever starts out at the top of its game?

Three.js, created by Mr. Doob (whose examples I have showcased in the past), was created with the goal of making a lightweight 3D engine with a very low learning curve. The engine renders using SVG, Canvas, and WebGL. Within the 3D engine you can create simple to complex geometry, lights, cameras, animate and materials.

So it’s almost like a stripped down version of the Blender software, save the fact that you’ll be programming your 3D instead of working with it in a real-time space. At times, three.js can be finicky, and if you need to take a moment to try and reverse engineer several of their examples and really understand what it is that drives the engine. For the nature of this article most of you reading may not have a working knowledge of how to model in 3D, then there may be some of you, like me, who have an extensive background in 3D work. Hopefully by the end of this portion in our Canvas related journeys, both the beginner and the expert will meet at a juncture point.

While working in 3D there are several things you must consider when it comes to setting up everything. You’ll want to consider what renderer you’ll be putting your final product on, any cameras placed within your scene, the scene itself, and any objects or materials in said scene. Think of it as digital stage design, and you’re the stage manager. Another thing you’ll need to consider is which browser supports what feature. In part 1 of the Canvas series I touched on the excanvas.js file that aids with the cross browsers issues with Canvas for browsers like IE, unfortunately excanvas.js only supports the 2D API. Chrome or a close second being the Firefox browser may be your safest bet in rendering. IE9 only supports Canvas rendering, so I wouldn’t bet on IE8 or 7 to be of any help. One advantage that WebGl has over Canvas, is that WebGL will run on your graphics cards freeing up a lot of your CPU to concentrate on other things interactions, etc.

Let’s begin by coding out our scene:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script src="js/three.js"></script>

<script type="text/javascript">
     var width = 500, height = 330;

     //let's add a camera to our scene
     var angle = 90, aspect = width/height, near = 0.1, far = 10000;

     var $wrap = $('#wrap');
     var $scene = new THREE.Scene();
     var camera = new THREE.Camera( angle, aspect, near, far );
     var renderer = new THREE.WebGLRenderer();

     camera.position.z = 300;
     renderer.setSize (width, height);
     $wrap.append(renderer.domElement);
</script>

The two first variables set in our script are the width and height of our canvas. if you’re not familiar with camera work, we added the camera to our scene then set aspect ratio, and the focal distances with the ‘near’ and ‘far’ variables. The wrap is our Canvas ID and we also set the scene, camera and render engine into place. We set the z-depth of our camera to 300 due to the fact that it begins at 0,0,0 so we can see what we’ve made; then tied it all up with our DOM Element.

Did you think it would be any worse than half of the code in my previous articles?

Since we’ve set everything in place we can now begin to add objects to our scene. If any of you are familiar with your basic 3D objects in 3D Studio Max, Blender, or Maya, then you know there are a number of basic objects we can create:

  • Plane
  • Cube
  • Sphere
  • Cylinder
  • Cone

It All Began with a Plane

Adding these objects to our WebGL with three.js is rather simple too. Let’s begin with the simplest of the object the plane. To create a plane we create a new variable properly name ‘plane’ like so:

var plane = var THREE.Mesh( new THREE.PlaneGeometry(450, 450), new THREE.MeshBasicMaterial({ color: 0xFF4200; }));

So above we’ve stated that we want our plane to be a square, 450 pixels wide by 450 pixels tall, and also set the color using the ‘MeshBasicMaterial’ method. Adding the variable of ‘Mesh’ to the beginning of our string guarantees that the mesh is placed in our scene. Some people may write their Mesh geometry as just ‘Plane’ instead of ‘PlaneGeometry’. I’ve tried it both ways to be honest, and using ‘PlaneGeometry’ tends to yield better results. All that’s left for you to do is add the plane to our scene we’ve set up like so:

scene.addChild(plane);

The variables, if you haven’t guessed, change to suit the object placed in our scene. You can set variables ahead of time to pass through the parameters of our scenes objects:

var width = 450,
     height = 450;

var plane = var THREE.Mesh( new THREE.PlaneGeometry(width, height), new THREE.MeshBasicMaterial({ color: 0xFF4200; }));

This helps organize our JS code a little better. I know it’s easy for me at times to get turned around in my own code. That’s why we comment and organize folks. Now that you got the hang of building a simple plane object down let’s jump into creating other simple objects. In 3D it doesn’t get more basic than cubed and sphere meshes. The only things that will change a bit will be the variable name and a couple of the parameters. For example:

new THREE.SphereGeometry(radius, segmentsWidth, segmentsHeight)

Let’s take a minute to talk about the segments that go into our sphere. You can set as many as you would like, but the number of segments corresponds with the level of detail. Your standard resolution for a smooth sphere might have up to 36 segments, just make sure to toy around with the segmentsWidth and segmentsHeight properties to get you desired result. Your radius property will help you size the sphere.

Like the above example, creating a cubed object also contains three different parameters, your standard width, height, and depth.

new THREE.CubeGeometry(width, height, depth);

When looking to create a cylinder or cone, there isn’t much different between the two objects. You can really tell when we look at the code:

//Creates a cylinder
new THREE.CylinderGeometry(radiusTop, radiusBottom, segmentsRadius, segmentsHeight, openEnded);

//The top radius is set to 0. We're using the CylinderGeometry like above except we're created a cone
new THREE.CylinderGeometry(0, radiusBottom, segmentsRadius, segmentsHeight, openEnded);

Adding Lights and Rendering the Scene

So now that we’ve created a scene and built our geometry in the scene, we can now start to add lights to illuminate things or create some broad lighting for a dramatic effect. Three.js will render our geometry, however it will appear as a flat 2D shape without lighting applied into our scene. One of the basic lighting rigs we can setup is a point light.

// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );

// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;

// add to the scene
scene.add(pointLight);

All that’s left for us to do with our scene is render everything. It’s as simple as:

renderer.render(scene, camera);

The below example is of an object using the CubeGeometry method, you’ll notice I included a snippet of code that makes up our object in the image:

Conclusion

We’ve just created 3D geometry in our browsers without any 3D software, it’s almost reminisent of Papervision. As I always like to say in these canvas articles, take some time to play around with the technology. Familiarize yourself with the ins and outs of Three.js.

With your basic geometry covered in this article, we’ll look at particle effects and text in part 6. If you think you may need a refresher course, go back to the beginning with Canvas Part: 1 and work your way through the tutorials.

Author: Joshua Rapp
Josh is currently the Creative Director at Rappsody Studios located in Jacksonville, FL and has been working in across the web for close to eight years. He has a soft spot for front-end development and comics.
  • http://www.logoguru.co.uk/pages/logo-design-contest.html Sam Anderson

    I have read the previous parts and found it so much useful experience to learn about design. Using 3d objects on browsers looks tough task but its being easy after reading this article. Hope to get learn with some more parts.