Geometry instancing with WebGL 2

webgl-logo

WebGL, based on OpenGL ES, brings hardware accelerated OpenGL to your browser, and version 2.0 is around the corner (specs). I’ve been playing around with WebGL (via JavaScript) for some time now (see my GitHub WebGL repo) and recently Google’s chrome (canary) got WebGL 2 support.

WebGL 2.0 adds some interesting new features, with geometry instancing being one of them, so I sat down and wrote a small demo that shows how to render the same instance of a single mesh with differing shader attributes using instancing and only one drawcall :

1
2
3
4
5
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer with offsets);
    gl.vertexAttribPointer(offset attrib location in shader, 3, gl.FLOAT, false, 12, 0);
    gl.vertexAttribDivisor(offset attrib location in shader, 1);
    ...
    gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, number of vertices to render, number of instances to render);

01

The attribute index is increased for each instance by the value set with gl.vertexAttribDivisor, so within the shader you can easily offset your vertex position, use different calculation parameters depending on the instance index, etc.

Though instancing is limited as it’s based on the same mesh only it’s still a great way to improve performance if you have to draw the same meshes multiple times, especially if combined with shaders.

Performance is pretty good, and even on my aged Radeon HD6850 I get 60fps at 1920x1200 with antialiasing enabled while drawing ~ 2 million triangles per frame.

You can find the sources for this demo in my repository. Note that you need a browser supporting WebGL 2 (Chrome carnary, and firefox seems to support it too) as well as a GPU (and ICD) that offers all features needed for WebGL 2.0 (OpenGL 3.3 should do the job).

webgl