Create A Rotating Cube in WebGL With Three - Js - Jonathan Petitcolas
Create A Rotating Cube in WebGL With Three - Js - Jonathan Petitcolas
js - Jonathan Petitcolas
Jonathan Petitcolas
During the last hackday at Marmelab, I decided to play with Three.js, one of the most
famous WebGL library. As hackdays are not hackweeks, I restricted myself to a simple
purpose: a rotating Marmelab logo. Today, I am going to present to you the results of my
experiments.
I splitted it into two posts. The first one is aimed to be a simple introduction to Three.js
shows how to generate a rotating cube. The second one will learn you how to modelize a
(not so) complex mesh in Blender and how to import it with correct texture. But for now,
let’s focus on the simple cube.
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 1/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
<!doctype html>
<html>
<head>
<title>Rotating logo - WebGL experiment</title>
</head>
<body>
<div id="container"></div>
<script src="js/three.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Now, let’s write our main.js file, containing all the logic of our rendering.
function init() {
}
function render() {
requestAnimationFrame(render);
}
init();
render();
We split our code into two parts: the initialization and rendering. The only interesting
thing to notice here is the call to requestAnimationFrame. This function acts similarly
than setTimeout, but in a slightly better way. To better understand it, let’s compare the
ways Javascript offers to repeat a function call.
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 2/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
The simplest is setInterval function. It takes two arguments: a function f to call and a
time interval n in milliseconds. This function will simply call f every n milliseconds,
whatever may happen. Sounds good at first glance. But what about if f execution time
lasts more than n milliseconds? Well, another call will be made, even if the first one was
not terminated, which may cause some glitches.
A better solution is to use the setTimeout function, which has the same signature. The
advantage with this one is it will not proceed to the next call until the current one has
been entirely processed. Yet, it is not the optimal solution.
The best solution you should use is the requestAnimationFrame function. Its signature
takes only one single argument: the function to call. Indeed, the browser will call it only
when it needs. Furthermore, this function is by far more clever than the other two ones,
as it pauses when current tab is not visible, saving battery and resources.
That’s why using requestAnimationFrame is the best choice (in this case). However,
this is not a generality. For long polling for instance, you should better use a
setInterval, unless you want to flood uselessly your server.
After this small digression, let’s come back to our main topic. To display something, you
need three elements: a scene, a camera and a renderer.
function init() {
scene = new THREE.Scene();
initCamera();
initRenderer();
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 3/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
function initRenderer() {
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
}
We first define global variables to store our three main elements. You should rather use
nested namespaces instead of. But for clarity, I voluntarily ignored this best practice. We
also defined two constants to keep the dimensions of our WebGL element (here, the
whole window).
Then, we initialize the scene. Nothing to say here, except the use of the THREE
namespace.
Next line, we initialize the camera. We use a perspective camera, as it is the most natural
choice. It takes four arguments:
the vertical viewing angle (also known as the eld of view, or fov). Generally, a
value between 60 and 70° is natural.
the ratio
the distance where the screen is located from the camera. Objects before this
distance will not be rendered (zNear in following schema).
the maximum sight of the camera: beyond this point objects will not be visible
(zFar in schema).
Here is a good and simple schema, taken from a tutorial of a Swiss university, explaining
previous points:
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 4/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
We move the camera at coordinates (0, 3.5, 5) and then orientate it to look at the center
of the scene through the lookAt position.
Finally, we initialize our renderer. As we are making WebGL, we use the WebGLRenderer.
Some other, such as CanvasRenderer exist, but they suffer of some restrictions. Do not
forget to append the renderer container into the DOM (here with a simple appendChild
call).
var cube;
function init() {
// ... (scene initialization)
initCube();
// ...
}
function initCube() {
cube = new THREE.Mesh(new THREE.CubeGeometry(2, 2, 2), new THREE.MeshN
scene.add(cube);
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 5/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
function render() {
renderer.render(scene, camera);
}
The previous code will display a cube seen from high angle view (as y position of our
camera is greater than our cube position).
Here are the two versions, respectively the anti-aliased and the aliased ones:
Bad looking on a simple mesh. I let you guess the result on more complex ones.
In the previous code, we just add a new mesh to the scene through the initCube
function. A mesh initialization requires two arguments:
Mesh geometry: where are located all the vertices and faces of our mesh.
Mesh material: how each face should be rendered? Colors and physical properties
(as brightness or opacity) are set here.
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 6/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
We just define a cube of 2 units edge, with default material (each face will be of a
different color).
Do not forget to call the renderer to see your cube, by calling the render function. We
could have put it in the init function in this static case. However, as our cube will move,
we have to render the scene at each frame.
function rotateCube() {
cube.rotation.x -= SPEED * 2;
cube.rotation.y -= SPEED;
cube.rotation.z -= SPEED * 3;
}
function render() {
requestAnimationFrame(render);
rotateCube();
renderer.render(scene, camera);
}
We play with the rotation angle of our cube, and just call the rotation function before
rendering our cube.
Nice looking result for very few lines of code, isn’t it? Demonstration and source code are
both available on GitHub.
In the next post, we will see how to render a more complex mesh with Three.js,
modelized in Blender.
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 7/9
9/4/2018 Create a rotating cube in WebGL with Three.js - Jonathan Petitcolas
Sort by Best
Recommend 1 ⤤ Share
LOG IN WITH
OR SIGN UP WITH DISQUS ?
Name
Indeed, the second part has not been done yet. To be complete, I need to
make some screencasts about it, and that's a LOT of work. That's why it is still
in my drafts. For a WIP view, have a look on GitHub:
https://github.com/jpetitco...
△ ▽ • Reply • Share ›
https://www.jonathan-petitcolas.com/2013/04/02/create-rotating-cube-in-webgl-with-threejs.html 9/9