WebGL - Shaders: A Beginner's Guide
Hello, aspiring programmers! Today, we're going to embark on an exciting journey into the world of WebGL Shaders. Don't worry if you've never written a line of code before – I'll be your friendly guide through this colorful landscape of computer graphics.
What are Shaders?
Before we dive in, let's understand what shaders are. Imagine you're painting a picture. The canvas is your computer screen, and shaders are like magical paintbrushes that tell the computer exactly how to color each pixel. Cool, right?
Data Types
In the shader world, we have some special data types to work with. Let's look at them:
Data Type | Description | Example |
---|---|---|
float | A single precision floating point number | 3.14 |
vec2 | A 2D vector | vec2(1.0, 2.0) |
vec3 | A 3D vector | vec3(1.0, 2.0, 3.0) |
vec4 | A 4D vector | vec4(1.0, 2.0, 3.0, 4.0) |
mat2 | A 2x2 matrix | mat2(1.0, 2.0, 3.0, 4.0) |
mat3 | A 3x3 matrix | mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0) |
mat4 | A 4x4 matrix | mat4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0) |
Don't worry if these seem overwhelming – we'll use them step by step!
Qualifiers
Qualifiers are like special labels we put on our variables. They tell the shader how to treat these variables. Here are the main ones:
Qualifier | Description |
---|---|
attribute | Input values that change per vertex |
uniform | Input values that stay constant for all vertices |
varying | Values passed from vertex shader to fragment shader |
Vertex Shader
The vertex shader is like the skeleton of our 3D model. It calculates where each point (vertex) of our model should be on the screen. Here's a simple vertex shader:
attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}
Let's break this down:
- We declare an
attribute
calledaVertexPosition
- this is the position of our vertex. - We have two
uniform
matrices - these help us position and project our 3D model onto a 2D screen. - In the
main
function, we calculate the final position of our vertex.
Fragment Shader
If the vertex shader is the skeleton, the fragment shader is the skin. It decides the color of each pixel. Here's a simple fragment shader:
precision mediump float;
void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
This shader is painting everything red! The vec4(1.0, 0.0, 0.0, 1.0)
represents full red, no green, no blue, and full opacity.
Storing and Compiling the Shader Programs
Now that we've written our shaders, we need to tell WebGL about them. Here's how we do it in JavaScript:
function getShader(gl, id) {
const shaderScript = document.getElementById(id);
if (!shaderScript) return null;
const str = shaderScript.text;
let shader;
if (shaderScript.type === "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type === "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
This function does a few things:
- It finds our shader code in the HTML document.
- It creates a shader of the right type (vertex or fragment).
- It compiles the shader and checks for errors.
Combined Program
Finally, we need to combine our vertex and fragment shaders into a program:
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialize shaders");
}
gl.useProgram(shaderProgram);
This code creates a program, attaches our shaders, links the program, and tells WebGL to use it.
And there you have it! You've just taken your first steps into the world of WebGL shaders. Remember, like learning any new language, it takes practice. Don't be discouraged if it doesn't click right away – keep experimenting and soon you'll be creating amazing 3D graphics in your web browser!
In my years of teaching, I've seen countless students go from complete beginners to shader wizards. One of my students even used these skills to create a virtual art gallery for her final project – imagine walking through a 3D museum right in your web browser!
So, what will you create with your new shader skills? The only limit is your imagination! Happy coding, future graphics gurus!
Credits: Image by storyset