Notice: Undefined index: order_next_posts in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 194

Notice: Undefined index: post_link_target in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 195

Notice: Undefined index: posts_featured_size in /nas/content/live/gadgetmag/wp-content/plugins/smart-scroll-posts/smart-scroll-posts.php on line 196

WebGL: How to create assets for 3D environments

Tendril’s Diego Tres describes the creation of Sankhara’s asteroid-laden WebGL environment

Tendril’s Diego Tres describes the creation of Sankhara’s asteroid-laden WebGL environment


1. Plan and prototype

The Sankhara site was planned, developed and tested over just nine days, as a promotional website for a proposed VR experience. As part of the remit it needed to work on mobile, and a template solution was out of the question. In the first phase, the team designed and coded a functional prototype connecting the libraries.

2. Frameworks and libraries

Since the website has no backend, Middleman was used ( as the static site generator to take advantage of tools like LiveReload (, JavaScript compression, CSS compression and Sass. Also, to make the WebGL easier to work with, the 3D JavaScript library three.js was employed. Finally, as you can see from the includes below, AmplifyJS ( was used as a publish/subscribe pattern for the communication between the UI modules and the WebGL scene:

//= require ./_vendors/jquery-2.1.4
//= require ./_vendors/jquery.fullpage
//= require ./_vendors/tween
//= require ./_vendors/amplify.core
//= require ./_vendors/howler
//= require ./_vendors/three
//= require ./_vendors/three.OBJLoader
//= require ./_vendors/dat.gui
//= require ./_vendors/stats
//= require ./_vendors/orbitcontrols
// APP
//= require ./_app/scenario
//= require ./_app/debug
//= require ./_app/loading
//= require ./_app/bootstrap

3. Productivity in WebGL

Anybody who has set up a WebGL scene via code knows how boring and slow it is to position every 3D object (geometries, cameras, lights and so on) into place. You can easily lose hours trying to put every 3D object in its exact position (x, y and z). So, to help modify them during execution, a lightweight graphical UI for changing variables within JavaScript called dat.GUI was used.

4. Generate multiple asteroids

In order to simulate all the asteroids and keep the website lighter in the process, only a single asteroid was created in 3ds Max and imported into JavaScript as an OBJ file. With that single OBJ, randomising size, speed, rotation and position attributes could simulate tons of asteroids.

// Load geometry from cache
var geometry = APP.files['models/asteroid.obj']
// Define asteroid's material
var material = new THREE.MeshPhongMaterial({
color: '#fff',
map: APP.files['images/textures/asteroid_map.jpg'],
aoMap: APP.files['images/textures/asteroid_ao.jpg'],
specularMap: APP.files['images/textures/asteroid_specular.jpg'],
normalMap: APP.files['images/textures/asteroid_normal.jpg'],
shininess: 1,
normalScale: new THREE.Vector2(1, 1)
// create the asteroid
var asteroid = new THREE.Mesh( geometry, material );

5. Produce texture maps

An important part of modelling 3D objects would also be applying texture. As the previous step shows, a collection of JPG files among the site assets are referenced to be mapped onto the asteroids. These texture maps, along with those for the black hole background elements, were produced using Quixel’s NDO Painter for adding powerful surface detail drawing capabilities within Photoshop.