Wednesday, January 15, 2014

Using WebGL for Earth data mapping.

I have been using WebGL for some time for presenting shaded plots and other information on the Earth's surface. Examples are here, here, and here. Merits of WebGL include:
  • Dynamic tracking. You can drag the sphere plot to any orientation and magnification, as with Google Earth.
  • Good and convenient shading for continuous fields
  • Integrated with Javascript and HTML5 canvas.
I had said that I would say something about my experience with WebGL. I have been writing a generic program to do a world plot from input data files, which I hope to blog about. Here I will describe just what are the essentials of writing a WebGL program for these relatively simple circumstances.

  WebGL is an version of OpenGL, where programming is done in Javascript embedded in a HTML file and implemented by the browser. Reference material for OpenGL mostly comes from the Khronos Group, eg here, here, and here. Specifically for WebGL, there is a handy reference card. various people provide online tutorials; I've benefitted from Greggman and this site (link is to a "simple" program which does indeed display the minimal requirements).

The best place to find out about the HTML and Javascript (JS) facilities I use is W3C Schools. It has an environment where you can try out and modify code fragments for all kinds of commands and objects.

Writing a Javascript program

Javascript is like C, but with no i/o. So numerical data is entered as part of the code. JS is embedded in a HTML file between <script></script> tags. Links are made by assigning id's to HTML elements, and also call-backs (eg onclick="fn()"). fn() will typically be a JS function. JS can identify the elements by id, and modify them.

Script tags can link to an external source. JS can modify the original page; after it has appeared, it goes into listening mode, driven by events like mouse clicks.

 When developing a JS program, I usually place it in a file with minimal html, and show it in Firefox, with the free Firebug debugger add-on engaged. Then I can step through the code with all variables displayed in object hierarchy style.

 The JS program you write is downloaded and run on other peoples' computers, so there are security limitations. All code and data has to be readable by the user. You can't access file spaces, or even other windows - this can be a nuisance when embedding frames.

HTML 5 and WebGL

HTML 5 introduced new drawing facilities, particularly SVG and the canvas. A canvas is a HTML element, specifying an area of screen, and with a context offering JS functions etc that allow you to control drawing in the space. The common context is "2d", which I used extensively in the climate plotter. "webgl" is an alternative context, now offerred by most browsers.

 As said above, WebGL is based on OpenGL, which is in turn derived from the Silicon Graphics Iris GL of the 1990's. That was considered 3D graphics, but as Greggman maintains, WebGL is also a 2d context. It is capable of very rapidly implementing the 3D geometry transforms, but you have to write them. However, it supports the OpenGL ES shading language which makes this easy.

Structure of a WebGL App

You need to create a master object called a program. There can be several. To each you need to attach a vertex and a fragment shader. These are the little programs written in OpenGL ES that will be passed to the GPU. I usually write them (with JS help) as strings, which are compiled and attached.
The vertex shader typically specifies a 3D transform to the original vertex data, expressing user-induced motions. You may also link color information to the vertices.

The fragment shader tells what to do between vertices; it may reduce to just a color specification. 

Much of the rest of the program is concerned with putting the geometry data in buffers for GPU access, and connecting the names to the names in the shaders. When that is all done, you give a draw command - I use DrawArrays. At this stage you specify a shape (for which the buffers were designed). Options are POINTS, LINES, TRIANGLES, LINE_STRIP, TRIANGLE_STRIP, LINE_LOOP and TRIANGLE_FAN. In the first three, you just specify each item with all coordinates in full. That's bulky, so the remaining are ways of writing larger structures mitigating writing out the same coords several times. The shapes then appear (you can flush).

WebGL also has provision for perspective, lighting, texture etc, which go into the shaders. For presenting numerical plots, as I do, these aren't needed.

I linked above a minimal program. It doesn't do much, but shows the basic requirements.

Applications and a generic program.

At the start of this post I linked some Moyhu WebGL programs. The common theme is the display with points, lines or shading, of data on a spherical Earth that can be rotated or zoomed. I've written a program which formalises this, with data supplied in standard JS structures. I'll post about this soon.


Post a Comment