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.
Generative Art
Expert A noise-displaced icosphere with per-vertex colour cycling — every frame each vertex is scaled by layered trigonometric noise, producing an organic breathing shape surrounded by a particle halo. Three.js Docs
// High-res icosphere with vertex colours
const geo = new THREE.IcosahedronGeometry(1.0, 6);
const origin = new Float32Array(geo.getAttribute('position').array);
const colors = new Float32Array(origin.length);
geo.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const mesh = new THREE.Mesh(
geo,
new THREE.MeshBasicMaterial({ vertexColors: true })
);
scene.add(mesh);
// Layered trig noise — organic, no imports needed
const noise = (x, y, z, t) =>
Math.sin(x * 2.1 + t) * Math.cos(y * 1.9 - t * 0.7) +
Math.sin(z * 2.3 + t * 0.5) *
Math.cos(x * 1.7 - y * 2.1 + t) * 0.5;
const posAttr = geo.getAttribute('position');
const colAttr = geo.getAttribute('color');
const c = new THREE.Color();
let t = 0;
function animate() {
for (let i = 0; i < posAttr.count; i++) {
const ox = origin[i * 3], oy = origin[i * 3 + 1],
oz = origin[i * 3 + 2];
const n = noise(ox, oy, oz, t);
const scale = 1 + n * 0.28;
posAttr.setXYZ(i, ox * scale, oy * scale, oz * scale);
c.setHSL(((n * 0.5 + t * 0.04) % 1 + 0.6) % 1, 0.9, 0.6);
colAttr.setXYZ(i, c.r, c.g, c.b);
}
posAttr.needsUpdate = true;
colAttr.needsUpdate = true;
mesh.rotation.y = t * 0.18;
t += 0.01;
renderer.render(scene, camera);
requestAnimationFrame(animate);
}