Image Image Image Image Image
Scroll to Top

To Top





In 3D

By synergyseeker

Learning WebGL 3D: Getting Started with ThreeJS

On 07, Mar 2016 | 30 Comments | In 3D, HTML5, JavaScript, Learning, News, WebGL | By synergyseeker

WebGL, is a JavaScript API for creating and rendering graphics inside an HTML <canvas> element. We already used this element in previous lessons here, and the same basic concepts can be applied. In a basic sense, we are still using math to draw frames that we cycle through at high rates ( 60fps ) to create the optical illusion of motion.

webgl_logoIn the case of WebGL we are taping into the Web version of the OpenGL graphics language that is able to send instructions direct to the GPU for optimal performance. This means in theory, you can get wicked fast speed and performance, like native apps and games but in the web browser, but all without plug-ins. Now there are a limits of course, and bits missing from OpenGL in this web version but basically we are talking about super fast, high performance direct graphics rendering. Very cool. But at its core we have to still draw and render frame by frame using our good ole animation loop. Later on when we get into Shaders we’ll see how this differs.

So writing using the API directly is a ummm… pretty tedious and well hard, so thankfully there are awesomely smart folks out there that have abstracted most of the low level stuff and created libraries to help us out. There are options of course, but the library I have really enjoyed using is ThreeJS. It’s a great library that takes the complexity out of writing WebGL code for 3D by hand… Enough preamble! Let’s get started.
Similar to the intro lessons ( see super cool lessons here ), we start with a basic page. A little HTML5 container to house our CSS, JS and ThreeJS lib. So download the ThreeJS lib from here: OR link to it here: .

Make an empty CSS file and a an empty JS file and save them for later.

Make this base html file and save.

<title>Web GL Lesson 1: Getting Started</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src="libs/three.min.js"></script>
<script src="src/main.js"></script>

All right, so assuming you have all that we are set to start. You may have noticed we didn’t add a canvas element. We totally can in here, bu the ThreeJS lib will also create one for us if we want, so we’ll use that one for this first demo.

Let’s set up a super basic style sheet that just ensures we have a 100% x 100% canvas and no margins or padding in the way.

body,html { margin: 0; padding:0;}
canvas { width: 100%; height: 100% }

Ok. So there are some basic elements using ThreeJS and pretty much every 3D library. RENDER, SCENE, CAMERA. The Render basically handles the drawing of our scene and can be called whenever we want to ask the library to update the scene with the latest information. If nothing changes we don’t need to call it, but that would also be a pretty lame animation. So… we call it like we did in previous lessons, as frequently as possible up to 60FPS using the requestAnimationFrame. Something like this requestAnimationFrame( render ); Where render is a function that basically asks the rendered to render like this: renderer.render( scene, camera );

So the SCENE; this is basically a container. We add things to the Scene, like a Camera, Lights and Objects ( also called meshes ). As you can see by the model already, you could have multiple cameras, and scenes, and simply pass those to the renderer in the call above.

Ok, so let’s set this up with some basic code inside our empty JS file ( main.js ):

var scene = new THREE.Scene();
var fieldOfView= 45;
var aspect = window.innerWidth / window.innerHeight;
var nearClippingPlane = .1;
var farClippingPlane = 1000;
var camera = new THREE.PerspectiveCamera( fieldOfView, aspect, nearClippingPlane, farClippingPlane );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

That’s it. We instantiate a new ThreeJS Scene, a Camera with Aspect ratio ( almost always set to the ratio of the screen ) and a Renderer. Boom. Done. The Camera has some options. This one is a Perceptive camera versus an Orthographic Camera. This will give us perspective and make things look 3D and not flat. The Field of View is like a camera’s view cone or basically, what the camera can see, and what we will render in a scene. The clipping planes define what is too close to the camera to render and what is too far. Basically telling the camera not to worry about anything that is outside this range.

The ThreeJS render also generates a domElement if we want to use it, or we could attach it to own own element if we had added a canvas element previously. In this case we’ll just use the one generated.

Now if you run that, you see… well, nothing. Because we haven’t down anything with our new scene yet. In fact we haven’ even rendered it yet.

So let’s get the renderer doing it’s thing now, by adding this code to the JS:

var render = function () {
requestAnimationFrame( render );
renderer.render( scene, camera );


Cool, now if we run this we see…. well.. nothing still. But, not because we’ve busted anything, but because we haven’t actually added anything to the scene. We are basically perfectly rendering nothing at a sweet 60 fps. So let’s add something. Add the following code to the JS:

var geometry = new THREE.CubeGeometry( .1, 4,2 );
var material = new THREE.MeshNormalMaterial({"wireframe":true});
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;

Ok. So “objects” called meshes in 3D lingo, are comprised of 2 main things. Geometry, which explains the shape of the mesh, and Material, which is the skin or texture of the mesh. Geometry is super cool, because you can define virtually any type of shape or shapes you want, and refuse them over and over like a class. Geometry is basically a set of vertices or points that when combined form edges of shapes. Using materials and lights, we can make these look pretty awesome.

In this example we are using a simple geometry called CubeGeometry, which is a….cube. The cube geometry can have some values passed to it, such as width,height and depth. You can see here we made a thin sort of panel… reminds be of a flat screen TV.

The material is a basic MeshNormalMaterial which basically gives us some quick and easy color on our mesh so we can see it, we’ll dive into Materials more later. Materials can be passed a number of values. In this case we are setting the “wireframe” property to be true. This is so I can show you what a mesh looks like naked. I just said naked in a WebGL tutorial. You didn’t see that one coming did you? Oh, and we se the camera back at z = 5 so it is not right on top of the cube.

So if you run the above code now, you will see a super awesome wireframe mesh. Except it is kinda lame, because it just sits there.

Screen Shot 2016-03-07 at 1.52.55 PM
Let’s make it move.

Let’s add some simple rotation to this thing so we can see. We’ll add it into the render loop for now.

cube.rotation.x += 0.01;
cube.rotation.z -= 0.01;
So it should look like this now:
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.z -= 0.01;
renderer.render( scene, camera );

Now run that and we should see a cool, spinning mesh of awesome.

Screen Shot 2016-03-07 at 1.53.55 PM

Ok, so notice the wireframe material defines the triangles that make up our mesh. This is good to see, since the way light reacts to a mesh has to do with the vertices and triangles that comprise them and their vertex normals, (which is a fancy way of saying the angle light bounces back off the shape).

So let’s get some clothes on this bad boy. Remove that little flag in the Material line so it reads like this:

var material = new THREE.MeshNormalMaterial();

Now, run it again and you should see a cool spinning flat screen like cube.

Screen Shot 2016-03-07 at 2.51.47 PM

You can see this in action here.

That is the basic framework for setting up and getting started with ThreeJS to render some super smooth webGL in the browser.
Next up will be textures and lighting and a deeper looking into transforms.