WebGL is a powerful graphics API that allows you to render 3D graphics directly within the browser. It is built on top of the HTML5 canvas element, allowing you to utilize the GPU for complex rendering tasks. This article will walk you through the process of creating a simple 3D object using WebGL.
Setting Up WebGL in HTML
Before we can start drawing with WebGL, we need to set up our HTML document. We'll create a basic <canvas>
element that WebGL will use to render graphics.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL 3D Graphics</title>
</head>
<body>
<canvas id="webglCanvas" width="640" height="480">
Your browser does not support the HTML5 canvas tag.</canvas>
<script src="app.js"></script>
</body>
</html>
Initializing WebGL
Now, we'll move to JavaScript to initialize WebGL and clear the screen with a color. Start by getting a WebGL rendering context from the <canvas>
element.
// app.js
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('WebGL not supported, falling back to experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Your browser does not support WebGL');
}
Clearing the Canvas
First, choose a background color for our canvas which will be used to clear it.
// Set the clear color to black, fully opaque
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Clear the color buffer with specified clear color
gl.clear(gl.COLOR_BUFFER_BIT);
Creating Shaders
Shaders are programs written in GLSL and executed on the GPU. WebGL uses two types: vertex shaders and fragment shaders. Let's create some shaders to render a colored triangle.
const vertexShaderSource = `
attribute vec4 aVertexPosition;
void main(void) {
gl_Position = aVertexPosition;
}
`;
const fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // Red
}
`;
Compiling Shaders
Next, compile the GLSL shader source into executable WebGL shader programs.
function compileShader(gl, sourceCode, shaderType) {
const shader = gl.createShader(shaderType);
gl.shaderSource(shader, sourceCode);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('An error occurred compiling the shaders: ', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
const vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
const fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
Linking the Shader Program
After compiling, link the two shaders into a shader program.
function createProgram(gl, vertexShader, fragmentShader) {
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.error('Unable to initialize the shader program: ', gl.getProgramInfoLog(shaderProgram));
return null;
}
return shaderProgram;
}
const shaderProgram = createProgram(gl, vertexShader, fragmentShader);
Drawing a Triangle
Finally, we can draw a simple triangle using WebGL. We'll define the vertices of the triangle and render it using WebGL.
const vertices = new Float32Array([
0.0, 1.0, // Vertex 1 (x, y)
-1.0, -1.0, // Vertex 2 (x, y)
1.0, -1.0 // Vertex 3 (x, y)
]);
// Create a buffer to store the vertices
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const vertexPosition = gl.getAttribLocation(shaderProgram, 'aVertexPosition');
gl.vertexAttribPointer(vertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexPosition);
gl.useProgram(shaderProgram);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);
With this setup, you've rendered your first 3D triangle using WebGL! Although this example is simple, it forms the basis for more complex 3D graphics, enabling you to build applications like games and data visualizations. As you venture further, you'll likely need to work with more advanced concepts such as textures, lighting, and transformations. But for now, you've made a solid start in the world of WebGL by rendering your first 3D object.