CS424 Notes, 20 January 2012
- WebGL and JavaScript
- Here is a minimal example of a web page using WebGL:
<html> <head><title>Minimal WebGL</title> <script type="text/javascript"> function init() { var canvas = document.getElementById("cnv"); var gl = canvas.getContext("webgl"); if ( !gl ) gl = canvas.getContext("experimental-webgl"); gl.clearColor( 1, 0, 0, 1 ); gl.clear( gl.COLOR_BUFFER_BIT ); } </script> <body onload="init()"> <canvas id="cnv" width=500 height=400 style="background-color:black"> </body> </html>
- This example will show a red rectangle in a browser that supports WebGL. It will show nothing in a browser that does not even support the HTML5 canvas element. It will show a black rectangle if canvas is supported but WebGL is not.
- gl is the conventional name for the variable that represents a WebGL drawing context, which contains all the functions and constants the are defined in WebGL.
- gl = canvas.getContext("webgl") should get a WebGL drawing context, but doesn't seem to work yet in most browsers.
- gl.clearColor sets the color that will be used for clearing the drawing area. That is, it sets the background color. Colors are specified by 4 real numbers in the range 0.0 to 1.0 giving the RGBA components of the color.
- gl.clear( gl.COLOR_BUFFER_BIT ) does the actual clearing. gl.COLOR_BUFFER_BIT is an example of a WebGL constant. It tells gl.clear what to clear, since it can clear several different things.
- It is a long way from this to actually drawing anything!
- (How much JavaScript do we have to cover in class??)
- Here is a minimal example of a web page using WebGL:
- Overview of WebGL processing
- With WebGL, you draw primitives, which amount to points, line segments, and triangles.
- A primitive is defined by its vertices [plural of vertex] which are points in two or three dimensions.
- A vertex has attributes. An attribute associates a value to each vertex, representing some property of the vertex such as its coordinates or its color.
- A primitive can also have uniform properties, which are values associated to the primitive as a whole rather than to its vertices. A "uniform" is uniform over the entire primitive, but can vary from one primitive to another.
- WebGL does not assign any meaning to attributes and uniforms. That's entirely up to the programmer
- Uniforms and attributes are fed into a vertex shader, a program written in the shading language GLSL ES. The vertex shader is executed once for each vertex. (Remember that the attribute values can be different for each vertex.)
- Outputs from the vertex shader become inputs for the fragment shader, another program written in the shading language. Uniforms are also passed into the fragment shader. The fragment shader is executed once for each pixel in the primitive (that is for points along a line segment or inside a triangle). The fragment shader produces a color for its assigned pixel.
- (Note that fragments that lie outside the drawing area are "clipped" before they are sent to the fragment shader and are not processed further.)
- The color that is output by the fragment shader goes through some further processing before it shows up in the image (for example, alpha-blending with the previous color of the pixel).
- The multiple executions of the vertex shader are totally independent from one another. The multiple executions of the fragment shader are totally independent from one another. This makes the whole process very parallelizable -- which is why graphics processing can be made so fast.
- About coordinate systems
- You are not restricted to using actual pixel coordinate for drawing in WebGL. In fact, that wouldn't even make sense for three-dimensional drawing.
- Coordinates in WebGL are real numbers. There is a default coordinate system in which x goes from -1 at the left to 1 at the right and y goes from -1 at the bottom to 1 at the top. [The z coordinate is also limited to the range -1 to 1.] Values outside these ranges are clipped. This default coordinate system is referred to as clip coordinates.
- You can use different coordinates for drawing, but those coordinates have to be transformed into the default "clip" coordinate system. Your vertex shader is responsible for doing this.
- The original coordinates that you use for drawing are called object coordinates or modeling coordinates. These are the coordinates that you provide as an attribute for the vertices of the primitive.
- The vertex shader must assign a value to the special built-in variable gl_Position, which represents the coordinates of the vertex in the clip coordinate system. You are not limit to coordinates between -1 and 1, but only values in that range will show up in the image.
- There is one final transformation from clip coordinates to the actual pixel coordinates that are used for drawing on the canvas. That coordinate system is referred to as window coordinates.
- About varying variables
- Some properties vary from point to point within a primitive.
- One obvious example is the 2D or 3D "object" coordinates of the point. These coordinates are specified as an attribute of the vertices of the primitive. The values for points inside the primitive are obtained by interpolating the values at the vertices.
- Shader programs can have other values that act like the coordinates: The values for the fragments are obtained by interpolating the values at the vertices.
- Such values are represented by varying variables in the shader program. A varying variable must be declared in both the vertex shader and the fragment shader.
- The vertex shader assigns a value to the varying variable. Since this is done once for each vertex, you can get different values for different vertices in a primitive.
- The values from the vertices of a primitive are interpolated to give the values for fragments inside the primitive. The interpolated value for a fragment becomes the value of the varying variable in the fragment shader.
- The term "varying variable" is as opposed to "uniform variable".
- The flow of data through the shader programs:
- The seven WebGL primitives: