Master WebGL & Three.js: From Basics to 3D Rendering in the Browser
This article guides beginners through the fundamentals of computer graphics, explaining OpenGL, WebGL, GLSL, and the rendering pipeline, then demonstrates practical Three.js code for setting up scenes, cameras, lights, materials, and textures to create interactive 3D web experiences.
Learning WebGL and Three.js: Concepts and Practice
This article is contributed by the ByteDance Business Middle‑Platform Frontend team and has been authorized for publication by ELab.
Background
Before preparing this talk, the author searched Zhihu for "How to learn WebGL?" and collected several popular answers, which emphasized a combination of graphics, mathematics, computer architecture, operating systems, software engineering, design patterns, and C++.
Graphics + Mathematics + Architecture + OS + Software Engineering + Design Patterns + Compilers + (C++ skill) ≈ a better 3D software engineer.
The typical learning path suggested by experts includes:
Build a solid foundation in graphics theory and mathematics.
Choose a specific domain such as Web (WebGL, Three.js), 3D engines, or game development (Unity).
Continuously learn and practice until you can build your own tools.
Key Technologies
OpenGL
OpenGL (Open Graphics Library) is a cross‑language, cross‑platform API for rendering 2D and 3D vector graphics. It defines a standard that GPU vendors must implement.
OpenGL ES is a subset of OpenGL designed for embedded systems such as mobile devices.
WebGL
WebGL (Web Graphics Library) is a royalty‑free web standard based on OpenGL ES that exposes a low‑level 3D graphics API to JavaScript via the HTML5 canvas element.
It allows browsers to run GPU‑accelerated graphics directly from JavaScript.
GLSL
GLSL (OpenGL Shading Language) is the C‑like language used to write vertex and fragment shaders that run on the GPU.
Think of the rendering pipeline as a series of stages, each handled by a small program (shader).
Three.js
Three.js is a high‑level JavaScript library that wraps WebGL, providing an easier way to create 3D scenes without writing low‑level shader code, similar to how jQuery simplifies DOM manipulation.
Understanding the GPU Design Model
Rendering transforms a 3D scene into a 2D pixel image. The GPU is specialized hardware that performs the same operation on many pixels in parallel, relieving the CPU of heavy per‑pixel calculations.
The graphics rendering pipeline consists of several stages:
Vertex Shader – transforms vertex positions and attributes.
Primitive Assembly – builds geometric primitives.
Geometry Shader – optional processing of primitives.
Rasterization – converts primitives to fragments (potential pixels).
Fragment Shader – computes final color of each fragment.
Depth & Blending – handles occlusion and transparency.
Coordinate Spaces
3D objects are defined in several coordinate systems:
Local Space – object‑centric coordinates.
World Space – shared scene coordinates.
View (Camera) Space – coordinates relative to the camera.
Clip Space – normalized coordinates after projection.
Screen Space – final 2D pixel positions.
Transformations between these spaces rely heavily on linear algebra (matrix multiplication, translation, scaling, rotation).
Practical Three.js Walkthrough
Step 1 – Create Scene and Camera
import * as THREE from 'three';
class ThreeDemo {
constructor() {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.aspectRatio = this.width / this.height;
this.scene = null;
this.camera = null;
this.light = null;
this.renderer = null;
}
init() {
this.createScene();
this.createRenderer();
document.body.appendChild(this.renderer.domElement);
const render = () => {
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(render);
};
render();
this.axesHelper();
}
createScene() {
this.scene = new THREE.Scene();
this.scene.fog = new THREE.Fog(0x090918, 1, 600);
this.camera = new THREE.PerspectiveCamera(75, this.aspectRatio, 0.1, 2000);
this.camera.position.set(10, 10, 10);
this.camera.updateProjectionMatrix();
this.scene.add(this.camera);
}
createRenderer() {
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(this.width, this.height);
this.renderer.setClearColor(this.scene.fog.color);
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
});
}
axesHelper() {
const axesHelper = new THREE.AxesHelper(5);
this.scene.add(axesHelper);
}
}
const instance = new ThreeDemo();
instance.init();Step 2 – Add Lights and Geometry
// Ambient light
this.light = new THREE.AmbientLight(0x404040);
this.scene.add(this.light);
// Add a cube
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({ color: 0xaafabb });
this.scene.add(new THREE.Mesh(geometry, material));Step 3 – Add Directional Light
createLight() {
this.light = new THREE.AmbientLight(0x404040);
this.scene.add(this.light);
this.directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
this.directionalLight.position.set(0, 5, 5);
this.scene.add(this.directionalLight);
}Step 4 – Apply Materials and Textures
const geometry = new THREE.BoxGeometry(2, 2, 2);
const material = new THREE.MeshStandardMaterial({
map: textureLoader.load('.../RoofTilesTerracotta004_COL_1K.jpg'),
aoMap: textureLoader.load('.../RoofTilesTerracotta004_AO_1K.jpg'),
normalMap: textureLoader.load('.../RoofTilesTerracotta004_NRM_1K.png'),
transparent: true,
roughness: 0,
});
const model = new THREE.Mesh(geometry, material);
this.scene.add(model);Summary of Steps
Initialize Scene, Light, and Camera, then render them with a Renderer.
Load a Model, apply Material and Texture, position it, and add it to the Scene to obtain a visible 3D object.
Final Thoughts
If you have never systematically studied computer graphics, starting with Three.js is a practical way to grasp core concepts such as scenes, lights, cameras, shaders, and the rendering pipeline. Mastery of linear algebra and the GPU pipeline will later enable deeper exploration of WebGL and GLSL.
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.
