WebGL stands for Web Graphics Library, a JavaScript API that draws GPU-accelerated 2D and 3D graphics in a canvas element without plug-ins. WebGL 1.0 exposes the OpenGL ES 2.0 feature set and WebGL 2.0 exposes OpenGL ES 3.0. The Khronos Group publishes the specification, and Apple, Google, Microsoft and Mozilla are members of its WebGL Working Group. You get a context from a canvas with the context identifier webgl or webgl2.
WebGL is a low-level, shader-based API. You do not describe a scene. You upload data to GPU buffers and write small programs in GLSL (the OpenGL Shading Language) that the GPU runs.
canvas.getContext("webgl") returns a WebGLRenderingContext, and canvas.getContext("webgl2") returns a WebGL2RenderingContext. It returns null if the identifier is unsupported or the canvas already has a different context type.gl_Position.gl_FragColor in WebGL 1.drawArrays or drawElements sends buffered vertices through both shaders and rasterizes the result into the drawing buffer.bindBuffer and useProgram change what the next draw call uses.The example below compiles both shaders, draws one triangle that covers the whole 4 by 4 pixel surface, and reads the first pixel back. It ran in Node.js with the gl package, a headless WebGL 1.0 implementation, so the version string differs from a browser's. In a browser you would create the context with canvas.getContext("webgl") instead.
const gl = require('gl')(4, 4);
const vs = `attribute vec2 p; void main() { gl_Position = vec4(p, 0.0, 1.0); }`;
const fs = `precision mediump float; void main() { gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0); }`;
function shader(type, src) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
return s;
}
const prog = gl.createProgram();
gl.attachShader(prog, shader(gl.VERTEX_SHADER, vs));
gl.attachShader(prog, shader(gl.FRAGMENT_SHADER, fs));
gl.linkProgram(prog);
gl.useProgram(prog);
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW);
const loc = gl.getAttribLocation(prog, 'p');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
const px = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, px);
console.log(gl.getParameter(gl.VERSION));
console.log(Array.from(px));
console.log(gl.getError() === gl.NO_ERROR);
// WebGL 1.0 stack-gl 8.1.6
// [ 255, 128, 0, 255 ]
// true
WebGL 2 is based on OpenGL ES 3.0 and WebGL 1 on OpenGL ES 2.0. WebGL 2 adds 3D textures, sampler objects, uniform buffer objects, sync objects, query objects and transform feedback objects. It also makes vertex array objects, instancing, multiple render targets and fragment depth part of the core API, where WebGL 1 needed extensions. Request it with getContext("webgl2") and fall back to "webgl" when that returns null.
getContext gives null when WebGL is unavailable, and the user's device must also have hardware that supports it. Check the result before calling any method on it.false from getShaderParameter(shader, gl.COMPILE_STATUS) and ERROR: 0:2: '}' : syntax error from getShaderInfoLog. Log wording and line numbers vary by implementation. Check both after every compile.webglcontextlost on the canvas. Handle the event instead of assuming the canvas keeps drawing.webgl returns null. Use a separate canvas element.experimental-webgl was used by early or not yet conformant implementations. Request webgl and webgl2.