WebGL
Modified 2025-12-05
WebGL provides a bridge between javascript and the GPU using a the GLSL (OpenGL Shading Language). Here's a cheatsheet.
Rendering Pipeline

- The
verticesholds the data points. These data points get converted by - The
vertex shaderinto locations on the screen. - The
primitive assemblyconverts the points on the screen to points, lines, or triangles. The primitives build into a model. - The
rasterizationstep creates pixels for the primitives, so the fragment shadercreates colors for every point.- The
frame bufferis responsible for displaying it on the screen
Shaders & GLSL
Vertex Shaders

- receive data via
attributes,uniformsortextures - called once for each vertex
- must set
gl_Positoonto clip space coordinates (-1 to +1)
Y = +1 (top)
^
|
|
X = -1 <---------+---------> X = +1
|
|
v
Y = -1 (bottom)
Buffers & Attributes
Create a buffer and put data in them.
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, someData, gl.STATIC_DRAW);
const colorLocation = gl.getAttribLocation(program, "a_color");On initialization time, look up the location of the attribute.
const colorLocation = gl.getAttribLocation(program, "a_color");On render time, tell WebGL how to pull data out from the buffers and into the attributes.
gl.enableVertexAttribArray(colorLoc);
gl.vertexAttribPointer(colorLoc, 4, gl.UNSIGNED_BYTE, true, 0, 0);Now it's available in the shader.
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}Uniforms
Uniforms are values passed to the shader that stay the same for all vertices in a draw call. For example, screen offsets. Two shader programs are completely different environments, not shared.
Look up the location of the uniform at initialization time.
offsetLoc = gl.getUniformLocation(someProgram, "u_offset");Then setting the uniform.
gl.uniform4fv(offsetLoc, [1, 0, 0, 0]); And then use it in the shader.
attribute vec4 a_position;
uniform vec4 u_offset;
void main() {
gl_Position = a_position + u_offset;
}Look up the location of the uniform at initialization time/
Fragment Shader
- receive data via
uniforms,texturesorvaryings - called for every rasterized pixel
- must set
gl_FragColorto color space
Varyings
Pass data from the vertex shader.
attribute vec4 a_position;
uniform vec4 u_offset;
varying vec4 v_positionWithOffset;
void main() {
gl_Position = a_position + u_offset;
v_positionWithOffset = a_position + u_offset;
}To the fragment shader directly.
precision mediump float;
varying vec4 v_positionWithOffset;
void main() {
vec4 color = v_positionWithOffset * 0.5 + 0.5;
gl_FragColor = color;
}Textures
Textures are passed to the shader via a sampler2D uniform, and use
the GLSL texture2D function to extract a value out of it.
Create the texture and put data in it.
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
var data = new Uint8Array([
255, 0, 0, 255, // a red pixel
0, 255, 0, 255, // a green pixel
]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);Set the texture's filtering.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);At init time, look up the location in the shader program.
const someSamplerLoc = gl.getUniformLocation(someProgram, "u_texture");Bind the texture to a texture unit, and tell the shader which unit you bound it to.
const unit = 5;
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.uniform1i(someSamplerLoc, unit);