Page 1 of 5 Graphics 3D is the utimate. In this extract from Ian Elliot's book on JavaScript Graphics we look at how to get started with WebGL 3D
Now available as a paperback or ebook from Amazon.
JavaScript Bitmap Graphics With Canvas
Contents
- JavaScript Graphics
- Getting Started With Canvas
- Drawing Paths
Extract: Basic Paths Extract: SVG Paths Extract: Bezier Curves
- Stroke and Fill
Extract: Stroke Properties Extract: Fill and Holes Extract: Gradient & Pattern Fills
- Transformations
Extract: Transformations Extract: Custom Coordinates Extract Graphics State
- Text
Extract: Text, Typography & SVG Extract: Unicode
- Clipping, Compositing and Effects
Extract: Clipping & Basic Compositing
- Generating Bitmaps
Extract: Introduction To Bitmaps Extract : Animation
- WebWorkers & OffscreenCanvas
Extract: Web Workers Extract: OffscreenCanvas
- Bit Manipulation In JavaScript
Extract: Bit Manipulation
- Typed Arrays
Extract: Typed Arrays
- Files, blobs, URLs & Fetch
Extract: Blobs & Files Extract: Read/Writing Local Files Extract: Fetch API **NEW!
- Image Processing
Extract: ImageData Extract:The Filter API
- 3D WebGL
Extract: WebGL 3D
- 2D WebGL
Extract: WebGL Convolutions
<ASIN:B07XJQDS4Z>
<ASIN:1871962579>
<ASIN:1871962560>
This book has so far been about 2D graphics with Canvas using the standard graphics context. You will hear people say that if you want to do 2D graphics then a good way is to use WebGL. The reason is that WebGL is GPU-accelerated and hence has the potential to provide very fast animation. It also provides 3D graphics and animation. As a result learning it seems like a good investment – and it is, but only if you are serious about graphics. There is a steep learning curve associated with WebGL and in this chapter we start from the very basics and work up to some simple graphics with the intention of letting you see how involved it all is. In the next chapter we look at the slightly simpler problem of using WebGL for 2D graphics.
Using WebGL isn't easy for several reasons. Generally, the documentation isn't WebGL specific and simply refers you to the OpenGL/ES documentation pointing out differences. Even if you do know OpenGL, there are some surprising and unwelcome differences between it and the slightly more primitive WebGL. It all makes it difficult to get started on a 3D project.
The project we are about to make a start on, to draw a simple triangle, is going to presented as a single long function and it is not going to use any "helper" functions or any elaborate ways of doing things. The purpose of this example is to show you how things work with code that is simple and direct. While this is good from the point of view of understanding what is happening, when you start work on a real program you need to break it down into sensible functions, you need helper functions to keep the code compact and an "elaborate" way of doing something may turn out to be the best.
You can use any WebGL-supporting browser, but this example is based on using the latest Chrome.
The Canvas and the Viewport
There is a lot of initialization to do before you can start drawing anything and this is the case with most 3D programs. WebGL is particularly bad when it comes to lengthy initialization - there is nothing much that can be done about this. The first thing to do is set up a web page complete with a canvas object that we can use to draw on:
function createCanvas(h, w) {
var c = document.createElement("canvas");
c.width = w;
c.height = h;
return c;
}
function draw3d(){
var gl= document.body. appendChild(createCanvas(400,400)). getContext("webgl");
You should now test that the variable gl really does have a reference to the WebGL object, but for the sake of simplicity let's just assume it does.
The webgl context will return a WebGL 1 or WebGL 2 context depending on what the browser supports. WebGL 1 is supported by all major browsers apart from Safari. WebGL 2 uses a slightly modified form of shader language, but unless you enable this it is backward compatible with WebGL1. For this reason the rest of this chapter uses WebGL 1 and its shader language, even though there are some efficiency improvements in WebGL 2.
Finally we have to set the WebGL viewport to the area of the Canvas object that we want to use to render the 3D graphics. In most cases this is the whole of the Canvas:
gl.viewport(0, 0, canvas.width, canvas.height);
Shader Theory
The next standard initialization task is to set up a vertex and pixel shader. If you have used other 3D frameworks you might not be used to this idea, but modern graphics hardware has a programmable pipeline and WebGL and OpenGL support this.
There are no default rendering modes that you can fall back on - you have to specify how you want to process the 3D points and you have have to specify how to render them. There are no lights, no lighting effects and so on, unless you provide the shader code for it. This can make getting started more difficult, but in practice you can "borrow" standard shaders to create the lighting and rendering effects you want. When you become an expert then working out new shaders simply adds to the fun.
In most cases you have to supply two shaders - a vertex shader and a pixel, or fragment, shader. The vertex shader is all about how the point that you specify in 3D space is converted to the point that is plotted on the screen. It provides the transformation and projection processing and generally you use it to apply transformation and projection matrices onto the raw 3D data. The fragment shader is responsible for setting the color of the pixels that are within the area specified by the vertices. Exactly how it does this can be as simple as assigning a fixed color or as complex as working out what the color should be based on what light is falling on the surface in a 3D scene.
The whole point is that everything that happens is programmable using the shader code. In addition it is worth knowing that your shader code is executed in parallel by hundreds of processors – this is why GPU graphics are much faster than CPU graphics.
|