I'm working on a WebGL game using Three.js, its been a few days and I found my first issue, render time on big maps.

The game runs great, there are even some AI mobs that run around randomly like crazy, the problem comes when the game has to display many tiles at once (being many around 900 (30x30) on my Computer), if I zoom in the game runs at 60 solid FPS, here's the game demo so you can watch it in action.


You can move around with the classic WASD or arrow keys and zoom in and out with the MouseWheel.

Right now I'm creating a map like this (The project's code name is Kuxtal):

I have a singleton called Kuxtal, from which all the magic happens, I create a Kuxtal.Instance, which holds the renderer, scene, camera, and some functions to work with them.

Then I create a Kuxtal.Map, to which I pass the width & height as parameters and it runs:

for (var i = 0; i < this.width; i++) { // map.width
    for (var j = 0; j < this.height; j++) { // map.height
        var type = Math.ceil(Math.random() * 3); // 1-Grass 2-Dirt 3-Something else
        var tile = new Kuxtal.Tile(type, i, j);


This is my Kuxtal.Tile Class:

Kuxtal.Tile = function(type, x, z) {
    this.type = type;
    this.x = x;
    this.y = Math.random(); // A random elevation between 0 and 1 les me see the grid and looks nice
    this.z = z;

    this.sprite = new THREE.Mesh(new THREE.CubeGeometry(Kuxtal.TILE_SIZE, 1, Kuxtal.TILE_SIZE), new THREE.MeshPhongMaterial({color: 0xFFFFFF, map: Kuxtal.getTexture("grass")}));
    this.sprite.position.set(SELF.x * Kuxtal.TILE_SIZE, SELF.y, SELF.z * Kuxtal.TILE_SIZE);
    this.sprite.receiveShadow = true;= THREE.RepeatWrapping;

And the tiles are added to the scene on this Kuxtal.Instance.loadMap(map) function:

map.tiles.forEach(function(tile) {

Any suggestions on how to improve the performance?


great performance saving comes from caching geometries and materials.

In your case, create CubeGeometry and MeshPhongMaterial objects only once and then use them when creating tiles - each tile will be separate Mesh but all pointing to same instance of material and geometry objects.

Then do the same for all resources that can be reused - models, textures etc. Always think about what can you reuse and whether you really need to create a new object instance.

and btw - don't call those tile's meshes 'sprites' - it can be confusing as THREE.JS already has a type called Sprite.

  • \$\begingroup\$ Excellent! I knew that creating multiple instances of the same object many times was bad, now I feel stupid for doing it, thanks for making me remember such thing! \$\endgroup\$ – Jesuso Ortiz Jan 23 '14 at 22:52
  • \$\begingroup\$ Lovely! just lovely! I made the changes on the code, and I changed started increasing the number of tiles rendered on screen, I got to 10,000 tiles at once, sharing the geometry and the material, I had 60 solid FPS, I could continue increasing the number but the map was so big it went out of my skybox, so I will have to make changes to that if I want maps to be even bigger. Thanks again for your reply, the result was just awesome! \$\endgroup\$ – Jesuso Ortiz Jan 24 '14 at 19:13
  • \$\begingroup\$ I was glad to help, I had to go the same way and realize same things myself. Regarding your map going out of skybox - cool thing is to make skybox move with the camera. Every frame set skybox's position to be same as camera position (only position, not rotation) Then it will look more real (normally you don't see sky getting closer to you as you walk) and you also get rid of the problem that your map is getting out of skybox. \$\endgroup\$ – lot Jan 27 '14 at 15:32
  • \$\begingroup\$ Hello, how about tiles that has different geometries? Is there no way of optimizing? \$\endgroup\$ – majidarif Nov 15 '16 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.