Three.js and Babylon.js: a Comparison of WebGL Frameworks
Today’s web browsers have come a long way since the days of Sir Tim Berners-Lee and his Nexus software. Thanks to fantastic JavaScript APIs like WebGL, modern browsers are fully capable of rendering advanced 2D and 3D graphics without help from third-party plugins. By leveraging the horsepower of dedicated graphics processors, WebGL gives our web pages access to dynamic shading and realistic physics.
As you might have guessed, such powerful APIs typically come with a drawback. WebGL is certainly no exception and its downside comes in the form of complexity. Fear not, however, as we’ve explored two thoroughly capable frameworks that aim to make your life easier and possibly even a touch more productive when working with WebGL.
The humble origins of 3D frameworks
The ever popular Three.js along with the newer Babylon.js offer web developers an abstract foundation for crafting feature rich WebGL creations ranging from animated logos to fully interactive 3D games.
Three.js got its start back in April of 2009 and was originally written in ActionScript before being translated to JavaScript. Having been created before the introduction of WebGL, Three.js has the unique convenience of a modular rendering interface allowing it to be used with SVG and HTML5’s canvas element in addition to WebGL.
Babylon.js, being the relative newcomer, broke onto the scene in the summer of 2013. Brought to you by the minds at Microsoft, Babylon.js was introduced alongside Internet Explorer 11’s first official support for the WebGL API. Despite originating from Redmond’s labs, Babylon.js (as well as Three.js) maintains an open source license.
A subtle difference in design
Both Three.js and Babylon.js present easy to use libraries for handling the intricacies of WebGL animations.
Following the scene, renderer, camera, objects model of animation, these frameworks find themselves using similar methods for WebGL use. Utilizing either in your HTML is as simple as a one line script statement linking the respective JavaScript file. Note: Babylon.js has dependencies that require the open source Hand.js be included as well.
Three.js:
<script src="three.js"></script>
Babylon.js:
<script src="babylon.js"></script>
<script src="hand.js"></script>
The main difference between the two lies in their intended use. While it may be true either of these frameworks can be shoehorned into creating the same 3D animation, it’s important to know what each was created to accomplish.
Three.js was created with one goal in mind: to take advantage of web based renderers for creating GPU enhanced 3D graphics and animations. As such, this framework employs a very broad approach to web graphics without focusing on any single animation niche.
This flexible design makes Three.js a great tool for general purpose web animations like logos or modeling applications (great examples can be found here).
Where Three.js attempts to bring a wide range of animation features to the WebGL table, Babylon.js takes a more targeted approach. Originally designed as a Silverlight game engine, Babylon.js maintains its penchant for web based game development with features like collision detection and antialiasing. As previously stated, Babylon.js is still fully capable of general web graphics and animations as evidenced by the demos found on the front page of its website.
Side-by-side demonstration of WebGL technologies
To further demonstrate both the similarities and differences of these two frameworks, let’s build a quick 3D animation. Our project of choice will be a super simple cube with a slow rotation applied. In creating these two sample projects, you should begin to understand how the two technologies gradually diverge and show off their unique strengths. With that, let’s get started.
The first order of business when building creative projects of just about any kind is to initialize a blank canvas within which to contain our 3D animation.
Three.js:
<div style="height:250px; width: 250px;" id="three"></div>
var div = document.getElementById('three');
Babylon.js:
<div style="height:250px; width: 250px;" id="babylon">
<canvas id="babylonCanvas"></canvas></div>
var canvas = document.getElementById('babylonCanvas');
With Three.js we simply create an empty div as our container for the animation. Babylon.js on the other hand makes use of an explicitly defined HTML5 canvas to hold its 3D graphics.
Next, we load the renderer which will be responsible for preparing the scene and drawing to the canvas.
Three.js:
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
div.appendChild(renderer.domElement);
Babylon.js:
var engine = new BABYLON.Engine(canvas, true);
Nothing too fancy here, we just initialize the renderers (or engine in the case of Babylon.js) and attach them to our canvas.
Our next step gets a little more involved as we set up a scene to house our camera and cube.
Three.js:
var sceneT = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);
camera.position.z = 400;
Babylon.js:
var sceneB = new BABYLON.Scene(engine);
var camera = new BABYLON.ArcRotateCamera
("camera", 1, 0.8, 10, new BABYLON.Vector3(0, 0, 0), sceneB);
sceneB.activeCamera.attachControl(canvas);
var light = new BABYLON.DirectionalLight
("light", new BABYLON.Vector3(0, -1, 0), sceneB);
light.diffuse = new BABYLON.Color3(1, 0, 0);
light.specular = new BABYLON.Color3(1, 1, 1);
Here we create our scenes in almost identical fashion and then implement cameras (of which both frameworks support different types) from which we will actually view the created scenes. The parameters passed to the camera dictate various details about the camera’s perspective like field of view, aspect ratio, and depth.
We also include a DirectionalLight for Babylon.js and attach it to our scene to avoid staring at a pitch black animation later on.
With our canvas, scene and cameras all set up we just need to draw the cubes themselves before rendering and animating.
Three.js:
var cube = new THREE.CubeGeometry(100, 100, 100);
var texture = THREE.ImageUtils.loadTexture('texture.gif');
texture.anisotropy = renderer.getMaxAnisotropy();
var material = new THREE.MeshBasicMaterial({ map: texture });
var mesh = new THREE.Mesh(cube, material);
sceneT.add(mesh);
Babylon.js:
var box = BABYLON.Mesh.CreateBox("box", 3.0, sceneB);
var material = new BABYLON.StandardMaterial("texture", sceneB);
box.material = material;
material.diffuseTexture = new BABYLON.Texture("texture.gif", sceneB);
First, we create our cube objects of the specified size and then create our material/mesh (think texture) that will be painted onto the cubes. Any image file will work for the texture and both frameworks support mesh exports from 3D modeling tools like Blender.
In the final step we apply a gentle rotation for animation and then render the scene.
Three.js:
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render(sceneT, camera);
}
Babylon.js:
engine.runRenderLoop(function () {
box.rotation.x += 0.005;
box.rotation.y += 0.01;
sceneB.render();
});
Both Three.js and Babylon.js use an animation or render loop to update the canvas with a new, rotated drawing. You’ll also notice Three.js differs slightly from Babylon.js by attaching the camera at the point of render. Our end product is two cubes gently spinning in mid-air. Pretty easy, huh?
The tale of two frameworks
And there you have it. Two very capable WebGL frameworks built around the same foundation, yet focusing on different aspects of enhanced, Web based graphics.
You’ve seen first hand how similar their approaches to animation can be with both following the scene, renderer, camera, objects paradigm. Despite the similarities, Babylon.js subtly differentiates itself by focusing on traditional game engine requirements like engines and custom lighting.
In the end, these two relatively young frameworks enable web developers to more easily take advantage of the powerful 3D opportunities afforded by WebGL. As such, anyone with an interest in 3D web development should certainly take a closer look at this cutting edge technology.