WebGL Overview, Core Concepts, Native API Triangle, and Three.js Rotating Cube Tutorial
This article introduces WebGL as a JavaScript API for 2D/3D graphics, outlines its history and basic concepts, demonstrates drawing a triangle with the native WebGL API, discusses its drawbacks, and shows how to create a rotating cube using the Three.js framework with complete code examples.
WebGL is a JavaScript API that enables interactive 2D and 3D graphics in any compatible web browser without the need for plugins. It originated from a 2006 Mozilla Canvas 3D experiment and has progressed from the WebGL 1.0 specification released in March 2011 to WebGL 2.0, which was finalized in January 2017.
Basic concepts : WebGL runs on the GPU and requires paired shaders—vertex shaders (calculate vertex positions) and fragment shaders (determine pixel colors)—written in GLSL. These shaders are linked together into a shader program. Data can be supplied to shaders via attributes/buffers, global variables, textures, or varyings.
Working principle : When rendering a primitive such as a triangle, the vertex shader runs for each vertex to produce clip‑space coordinates, and the fragment shader runs for each generated fragment to produce color values, after which rasterisation creates the final pixels.
Native WebGL API – drawing a triangle :
function webglInit() {
const canvasEl = document.createElement('canvas'); // canvas element creation
canvasEl.width = document.body.clientWidth; // set canvas width
canvasEl.height = document.body.clientHeight; // set canvas height
document.body.append(canvasEl); // add canvas to body
if (!canvasEl.getContext('webgl') && !canvasEl.getContext('experimental-webgl')) {
alert("Your Browser Doesn't Support WebGL");
return;
}
const context = canvasEl.getContext('webgl') ? canvasEl.getContext('webgl') : canvasEl.getContext('experimental-webgl');
context.viewport(0, 0, context.canvas.width, context.canvas.height);
return context;
}
const gl = webglInit();
// vertex shader
const vShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vShader, `
attribute vec4 v_position;
void main() {
gl_Position = v_position; // set vertex position
}
`);
gl.compileShader(vShader);
// fragment shader
const fShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fShader, `
precision mediump float;
uniform vec4 f_color;
void main() {
gl_FragColor = f_color; // set fragment color
}
`);
gl.compileShader(fShader);
// program linking
const program = gl.createProgram();
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);
gl.useProgram(program);
const color = gl.getUniformLocation(program, 'f_color');
gl.uniform4f(color, 0.93, 0, 0.56, 1);
const position = gl.getAttribLocation(program, 'v_position');
const pBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0.5,
0.5, 0,
-0.5, -0.5
]), gl.STATIC_DRAW);
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(position);
gl.clearColor(0, 1, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);The native API requires extensive boilerplate, shader programming, and manual buffer management, making it costly for beginners.
Frameworks that simplify WebGL development : Three.js (comprehensive but limited official docs), Cesium.js (focused on 3D maps), and Babylon.js (widely used overseas).
Three.js – rotating cube example :
var renderer;
function initThree() {
width = document.getElementById('canvas-frame').clientWidth;
height = document.getElementById('canvas-frame').clientHeight;
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
document.getElementById('canvas-frame').appendChild(renderer.domElement);
renderer.setClearColor(0xFFFFFF, 1.0);
}
var camera;
function initCamera() {
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
camera.position.set(0, 10, 5);
camera.up.set(0, 0, 1);
camera.lookAt(new THREE.Vector3(0, 0, 0));
}
var scene;
function initScene() {
scene = new THREE.Scene();
}
var cube;
function initObject() {
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
cube = new THREE.Mesh(geometry, material);
scene.add(cube);
}
function render() {
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
function threeStart() {
initThree();
initCamera();
initScene();
initObject();
render();
}
document.addEventListener('DOMContentLoaded', function() { threeStart(); });The accompanying HTML file creates a <div id="canvas-frame"></div> container and loads Three.js. When run, it displays a rotating green cube.
Conclusion : While native WebGL offers full control, its steep learning curve and verbose code make frameworks like Three.js preferable for most developers, especially beginners. Nonetheless, mastering the native API remains valuable for advanced custom effects.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
