Code
Three.js
Hello Cube
Scene, PerspectiveCamera, WebGLRenderer, and a rotating cube — the Three.js hello-world.
Geometries
Six built-in geometries (Box, Sphere, Cone, Cylinder, Torus, Icosahedron) spinning with MeshNormalMaterial.
Materials
Basic, Normal, Lambert, Phong, and Standard materials compared side-by-side on identical spheres.
Lighting
Three coloured PointLights orbiting a white PBR sphere — AmbientLight, PointLight, and dynamic colour mixing.
Animation
Three objects animating with independent rotation, vertical sine oscillation, and pulse scaling.
Particle System
3 000 particles in a BufferGeometry — each bouncing inside a volume, uploaded to the GPU every frame.
Shader Material
Custom GLSL vertex and fragment shaders — sine-wave vertex displacement with animated RGB colour cycling.
Generative Art
Noise-displaced icosphere with per-vertex colour cycling — organic 3D generative art from layered trig noise.
Particle System
Advanced 3 000 particles simulated with BufferGeometry and PointsMaterial. Each particle bounces inside a bounded volume — position data lives entirely in a typed array for maximum GPU throughput. Three.js Docs
const COUNT = 3000;
const BOUND = 4;
const positions = new Float32Array(COUNT * 3);
const velocities = new Float32Array(COUNT * 3);
for (let i = 0; i < COUNT * 3; i++) {
positions[i] = (Math.random() - 0.5) * BOUND * 2;
velocities[i] = (Math.random() - 0.5) * 0.025;
}
const geo = new THREE.BufferGeometry();
const posAttr = new THREE.BufferAttribute(positions, 3);
geo.setAttribute('position', posAttr);
const mat = new THREE.PointsMaterial({
color: 0x88ccff, size: 0.055,
sizeAttenuation: true, transparent: true
});
const points = new THREE.Points(geo, mat);
scene.add(points);
function animate() {
for (let i = 0; i < COUNT * 3; i++) {
positions[i] += velocities[i];
if (Math.abs(positions[i]) > BOUND)
velocities[i] *= -1; // bounce
}
posAttr.needsUpdate = true; // upload to GPU
points.rotation.y += 0.0015;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}