Last year, we investigated then implemented massive and very fast rendering of hundred of thousands of points using WebGL. We took the opportunity of the recent OpenLayers 3 code sprint in Austria to implement a Proof of Concept (PoC) demonstrating line and polygon rendering using WebGL.
This first example shows a map with the base layer, points, lines and polygons, all drawn using WebGL.
WebGL lines and polygons
The second example shows countries (Polygon and MultiPolygon features), also drawn using WebGL. If the examples do not display correctly, please check here if your browser supports WebGL.
WebGL vector layer
Even though the developments are at an early stage, it is easy to notice that panning, rotating and zooming the map are already very smooth.
WebGL supports rendering lines out of the box, and this is what we are using in this prototype. We are creating an array of pairs of vertices (a batch) and we are passing it to WebGL for rendering.
There are a few WebGL limitations though:
- joins are not supported: there is some space between two consecutive lines.
- thick lines are only supported on Mac and Linux: all lines have a width of 1 pixel on Microsoft Windows
- lines are aliased: they appear rough on the screen.
Despite these limitations, we intentionally implemented line rendering this way as it is the simplest technique and it works well for the scope of this PoC.
In order to overcome these limitations, we should triangulate the lines; basically, line ends should be duplicated on the CPU then efficiently moved in the vertex shader. A line segment would be represented by two triangles.
WebGL has no support for rendering polygons, so we implemented it using only two draw calls.
- First, the polygon interiors are rendered using a batch of triangles. We triangulate the polygons and create a batch with an array of vertices and an array of triangle indices. The color is stored on each of the vertices, which allows to draw all polygons in a single draw call.
- Then the polygon outlines are rendered using a batch of lines. The line renderer described above is reused.
A limitation of our technique is that we duplicate the color on each vertex since using a uniform would prevent batching. An idea to save resources while still allowing batching would be to use a color atlas and only store a texture coordinate on each of the vertices. Only one draw call would be required.
As a side note, we use the promising earcut library for triangulating the polygons in this PoC.
This prototype provides a concrete first step toward implementing fast and reliable rendering of lines and polygons using WebGL. We are pleased by the smoothness we already get without any optimization. At Camptocamp, we are very excited by the performance and the full control WEBGL offers. If you are also looking for pushing the limits of current rendering, please get in touch with us!