|Written by Ian Elliot|
|Monday, 06 December 2021|
Page 5 of 5
As in most first examples, we are going to pass a 3D array to the shader that gives the position of each vertex, but it is important to know that you can pass data that is something other than position. You can even pass multiple arrays to different attributes. Each attribute is read one element at a time when the vertex shader is run. Think of a for loop processing two or more arrays in parallel.
This is more complicated than processing a uniform, but we are creating and using an array of data.
In this simple case the only vertex attribute that the shader processes is its position. The shader has a variable called:
attribute vec3 vertexPosition;
var vertexPos = gl.getAttribLocation( program,
For it to behave like an array attribute we have to associate it with a buffer in the GPU. To do this we first have to create a buffer object - this is a completely general buffer without any particular structure - and bind it to the WebGL object's array buffer:
var vertexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
After this we have a buffer in the GPU, but it isn’t associated with any attribute in the vertex shader. To associate the structure-less, name-less buffer we have just created with the attribute in the vertex shader we need to use:
gl.vertexAttribPointer(vertexPos, 3.0, gl.FLOAT, false, 0, 0);
Let’s draw a single triangle to get started:
var z = 4; var vertices = new Float32Array( [-0.5, 0.5, z, 0.5, 0.5, z, 0.5, -0.5, z]); gl.bufferData(gl.ARRAY_BUFFER, vertices,
If you enable it, WebGL will use its data whenever you ask for a draw or re-draw of the scene. If you don’t enable it then the attribute will behave like a uniform and you can set it in the usual way.
Final Setup and Drawing
Now we are almost ready to render the model, but there are still some very simple initialization steps we need to take. The first is to set the value that the color will be cleared to:
gl.clearColor(0.0, 0.0, 0.0, 1.0);
This doesn’t clear the buffer, it just sets the default color that it will be cleared to. Next we set the way that "culling" is performed.
These two methods set up the system to remove pixels that are behind other pixels in the 2D rendered scene. Without them you would be able to see distant objects mixed in with closer objects. Now we can clear the buffers using the values we just set:
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
and finally we can ask the system to draw the triangle, or in general whatever is in the buffer:
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 3.0); gl.flush(); }
Notice that we have to specify the number of vertices that are in the buffer as the last parameter.
The result is a fairly unimpressive green triangle. However, it is a 3D green triangle. For example, if you change the z value the triangle changes its size. If you change the z value for different vertices then the triangle changes its appearance as it becomes skewed. Don't expect any lighting effects or shadows because we haven't used a shader that creates them.
From here you need to create more sophisticated shaders, use matrix operations to set up the view and position, define more complex models with color and texture attributes and experiment with lighting and animation.
You can see a complete listing of this program at www.iopress.info.
In Chapter But Not In This Extract
Now available as a paperback or ebook from Amazon.
|Last Updated ( Monday, 06 December 2021 )|