What is a Torus Knot?
A Torus Knot is a complex 3D mathematical shape that wraps around the surface of a torus (a donut-shaped object) in a spiraling, intertwined pattern. Unlike a simple torus, which forms a smooth circular ring, a torus knot loops around itself multiple times, creating a more intricate and visually interesting structure.
In Three.js, a Torus Knot is generated using the built-in
TorusKnotGeometry class. This allows developers to quickly create advanced procedural shapes without manually defining vertices. By adjusting parameters like radius, tube thickness, and segment count, you can create a wide variety of knot styles and levels of detail.
Torus knots are often used in 3D graphics, game development, and visual demos because they showcase lighting, shading, and animation beautifully. They’re also a great way for beginners to move beyond basic shapes like cubes and spheres and start working with more advanced geometry in Three.js.
LIVE DEMO
Interactive Torus Knot rendered in Three.js
Shop great deals on gaming supplies and accessories on Amazon. As an Amazon Associate I earn from qualifying purchases.
Step 1: Create Scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
Step 2: Create Torus Knot
const geometry = new THREE.TorusKnotGeometry(2, 0.6, 100, 16);
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Step 3: Add Lighting
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff, 0.4));
Step 4: Animate
camera.position.z = 8;
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
Full Working Code (Copy & Paste)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Three.js Torus Knot</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<style>
body {
margin: 0;
background: #0f172a;
overflow: hidden;
}
</style>
</head>
<body>
<script>
// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0f172a);
// Camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 6;
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// Torus Knot
const geometry = new THREE.TorusKnotGeometry(2, 0.6, 150, 32);
const material = new THREE.MeshStandardMaterial({
color: 0x2ad1d6,
metalness: 0.7,
roughness: 0.25
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
// Lighting
const ambient = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambient);
const light = new THREE.PointLight(0x2ad1d6, 2);
light.position.set(5, 5, 5);
scene.add(light);
// Animation
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
// Resize Handling
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>