Free 3D Scene

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.

  • dark
  • three.js
  • webgl
  • 3d model
  • lighting
  • interactive

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 &middot; 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.

Works with Claude · ChatGPT · Cursor · v0 · Bolt · Gemini
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. 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. 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. 3

    Build a Mesh from a Geometry, which defines the shape, and a Material, which defines how the surface reacts to light.

  4. 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. 5

    Handle resizing: update the renderer size, the camera's aspect ratio and its projection matrix, or the image will stretch.

  6. 6

    Animate in a requestAnimationFrame loop: change rotation or position a little, then call renderer.render(scene, camera).

  7. 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.

More 3d scenes