Three.js Torus Knot
A glossy 3D torus knot rendered with WebGL, lit by coloured lights, that rotates and leans towards the cursor. A complete, minimal Three.js scene to learn from.
The code
Plain HTML, CSS and JavaScript. Uses Three.js r160, loaded from a CDN, so there is nothing to install. Copy a single file, or choose "Full file" for a complete page you can save as index.html and open in a browser.
<canvas id="scene"></canvas>
<div class="overlay">
<span>Three.js · WebGL</span>
<h1>Real-time 3D in the browser</h1>
</div>The AI prompt
Paste this into an AI coding tool to generate the same 3d scene, then ask it to adapt the colours, text or framework to your project.
Create a minimal Three.js scene showing a glossy rotating torus knot, in a single HTML file. Setup: - Load Three.js as an ES module inside <script type="module"> with: import * as THREE from "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js"; - A full-screen fixed <canvas id="scene"> on a #05060f background, with a small overlay at the bottom: an uppercase orange label "Three.js · WebGL" and the heading "Real-time 3D in the browser". Scene: - WebGLRenderer using the canvas, with antialias and alpha enabled, and pixel ratio capped at 2. - PerspectiveCamera with a 45 degree field of view, positioned at z = 6. - A Mesh made from TorusKnotGeometry(1.2, 0.4, 220, 32) and a MeshStandardMaterial with colour 0x2506ad, metalness 0.65 and roughness 0.2. - Lights: an AmbientLight at intensity 0.35, a white DirectionalLight (intensity 2.2) from the upper right, an orange PointLight (0xff7b00) from the lower left and a cyan PointLight (0x06b6d4) from the right rear. Behaviour: - A resize function that calls renderer.setSize(width, height, false), updates camera.aspect and calls camera.updateProjectionMatrix(); run it on load and on window resize. - A requestAnimationFrame loop using THREE.Clock: rotate the knot on the Y axis at 0.4 radians per second and on the X axis at 0.2, and ease its position towards the pointer (x up to 0.6, y up to 0.4 units) with a 0.05 easing factor. - Skip the automatic rotation if the user prefers reduced motion. Add numbered comments explaining each part: renderer, scene, camera, mesh, lights, resize, loop.
How to build it, step by step
- 1
Load Three.js as an ES module. In a plain HTML file, use a script tag with type='module' and import from a CDN; in a React or Next.js project, install it with npm install three.
- 2
Create the three core objects: a Scene (the world), a Camera (the viewpoint) and a WebGLRenderer (which draws what the camera sees into a canvas).
- 3
Build a Mesh from a Geometry, which defines the shape, and a Material, which defines how the surface reacts to light.
- 4
Add lights. MeshStandardMaterial is physically based, so with no lights the object renders black. Coloured point lights on opposite sides give the glossy two-tone look.
- 5
Handle resizing: update the renderer size, the camera's aspect ratio and its projection matrix, or the image will stretch.
- 6
Animate in a requestAnimationFrame loop: change rotation or position a little, then call renderer.render(scene, camera).
- 7
Cap the pixel ratio at 2. Rendering at 3x on some phones triples the work for no visible gain.
Customisation tips
- Swap TorusKnotGeometry for IcosahedronGeometry, SphereGeometry or a loaded GLTF model; everything else stays the same.
- In React, use React Three Fiber (@react-three/fiber) to write the same scene as components.
- In Next.js, load the 3D component with next/dynamic and ssr: false, because WebGL needs the browser.
- Pause the loop with an IntersectionObserver when the canvas is off screen to save battery.