Learning Three.js

or WebGL for Dummies

Performance: Caching Material

This article is about performance and how caching can improve them. In WebGL, it is important not to push the same textures multiple times to the GPU. It uselessly slow down the rendering. As a rules of thumbs, the less data are exchanged between the cpu and the gpu, the better it is for performance.

A Basic Caching

three.js handles cache cleanly and eleguantly. If you instanciate a javascript object THREE.texture or a THREE.Material only once, it will be pushed only once to the GPU. It is the simplest way to avoid pushing them multiple times.

var material = new THREE.MeshLambertMaterial({map:THREE.ImageUtils.loadTexture( 'foo.jpg')});

Then you use this material as many times as you want, foo.jpg will be sent only once to the GPU. For example, let’s create many spheres.

var mesh = new THREE.Mesh( new THREE.SphereGeometry( 75, 20, 10 ), material );

This solution is simple and eleguant but may not be practical with a large code, like a game. In such case, you can use microcache.js. It is a micro library to handle in-memory cache which works in node and browser.

So Let’s Cache with microcache.js

It needs only 3 lines. To install microcache.js, download it and copy this line.

<script src="microcache.js"></script>

To instanciate a cache, use the following line.

renderer._microCache = new MicroCache();

As you likely noticed, it is attaching the cache to the renderer. Why do we do that ? First, it is required to support multiple renderers on the same page, each with it own cache. Additionnaly if you stop using a renderer, the cache will be automatically dropped by javascript garbage collector. Two nice features. Now lets create a texture and cache it.

var texture = renderer._microCache.getSet('heavy', THREE.ImageUtils.loadTexture('foo.png'));

This is it. It is as simple as that. Now maybe you wonder “yeah but how do i know what need to be cached”… I completly agree, it is always nice to get diagnostics from the system when optimizing performance.

Now Let’s Diagnose

You can check what is pushed to the GPU with WebGL inspector. It is a firebug-like to “debug, diagnose, and explore WebGL scenes”. You can see the texture tabs on the right. If you spot duplicates in there, you found rooms for optimization :) You can embed it in your own page application with a single line.

<script src="https://raw.github.com/benvanik/WebGL-Inspector/master/core/embed.js"></script>

That’s All Folks

As Terje Mathisen said, “All programming is an exercise in caching.” Caching is a efficient way to optimize your code. It is simple with microcache.js. The code is available on github here under MIT license. If you hit bugs, fill issues on github. Feel free to fork, modify and have fun with it :)