At a high level, the WebGL rendering process breaks down into three phases:
- More stuff happens inside the GPU.
- The GPU draws the results of all the stuff in an HTML canvas element.
Setting up this drawing process comes with a lot of initial ceremony. It might seem overwhelming without prior OpenGL programming experience, but this is a one-time cost. An early investment in a few different concepts becomes the foundation for creating a custom rendering pipeline tailored to the individual needs of a system.
A basic program that exercises every piece of the above diagram can be assembled from the bottom up. But first, some initial setup.
1 2 3 4 5 6 7 8 9 10
1 2 3 4
gl variable contains a reference to a WebGL rendering context. This context is the main interface for the WebGL API.
Shaders are pre-compiled drawing programs that run inside the GPU. They are written in a C-like language called GLSL and provide rendering instructions to the GPU. Two types of shaders are used in this pipeline example: Vertex and fragment.
Vertex shaders describe how to draw the vertices making up one or more polygons. For the purposes of this example, that means a list of two-dimensional coordinates. However, the vertex shader does not know the actual positions of these coordinates. It knows only that they exist, and that they will be available by way of some attribute provided when the program runs.
1 2 3 4 5 6 7
At runtime, an attribute named
a_position of the type
vec2 (a 2-dimensional vector) contains positional data about a vertex. Convert that vector into a
vec4 (4-dimensional vector) and assign it to the special WebGL global variable
gl_Position. This program runs once for every pair of vertex coordinates.
Fragment shaders describe the space between vertices. While the vertex shader was called once for each vertex, the fragment shader program is called once for each pixel in the space between those vertices. In this example, the fragment shader program describes the color of each pixel.
1 2 3 4 5
At runtime, each time the fragment shader program executes (for each pixel), assign a new 4-dimensional vector describing a color (in RGBA form) to the special WebGL global variable
gl_FragColor. In this case, the color is always white.
Hooking up shaders makes up a large chunk of the WebGL setup ceremony. The source code for the shaders must be compiled and linked together in an instance of a WebGL program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Once compiled, the process is not repeated unless the shader source code changes.
1 2 3 4 5 6 7 8 9
Create a buffer and an array containing positional data. Then, activate the buffer by “binding” it. Finally, declare that the data for the activated buffer is the array of positional data in the form of 32-bit floats.
The setup is finally complete. It’s time to draw.
1 2 3 4
First, declare a clear color of black (in RGBA form). Next, inform WebGL to clear the color buffer using the declared clear color. Then, declare a pointer to the WebGL attribute
a_position containing the vertex data. Finally, draw the buffered vertices as a pair of triangles.
The results may be slightly underwhelming for the amount of effort, but this lays the groundwork for more advanced applications.
In a more advanced WebGL application, the drawing section might be called repeatedly in a loop as the buffered data changes. Drawing 60 times each second results in a target frame rate of 60fps. Everything else is initial setup that may expand in size (i.e. additional buffers, more complex shaders), but otherwise looks very similar to this example. The complete example is available on Github and as a JSBin.
For more in-depth learning about WebGL, I recommend these resources:
- The WebGL Programming Guide is an introductory book that assumes no previous knowledge of WebGL, HTML, JavavScript, or OpenGL.
- Learning Three.js is a book covering a popular library that wraps WebGL in a higher-level abstraction. Three.js is great for getting things done, but it hides many implementation details.
- Learning WebGL is an older tutorial site based on an even older OpenGL tutorial. However, it has a wide variety of lessons covering many different aspects of WebGL.
- WebGL Fundamentals is a new(er) tutorial site covering more advanced WebGL concepts. Some preexisting familiarity with WebGL will be helpful here. In particular, the math sections are well done.
If you enjoyed this post, please consider subscribing.