Demo 04 · Lab
A thing in space
A faceted metal object that catches coloured light on its edges, turns slowly, and leans toward your cursor.
Use this when
The background should be an object, something sculptural that belongs to your brand.
Skip it if: A shader field would do. Paying a heavy library to render what amounts to a gradient is the most common three.js mistake.
The prompt
Add a 3D background to my hero section using three.js: a single dark metallic object floating behind the headline. Requirements: - One three.js scene on a full-viewport <canvas> behind the hero content. - The object: an icosahedron with flat shading and a dark metallic standard material (deep navy base colour, metalness ~0.85, roughness ~0.3), bright enough that its silhouette reads even between light hits. - Lighting: an ambient light strong enough to keep shadow sides visible, two coloured point lights, violet (#7C5CFF) upper-left, warm orange (#FF6A2A) lower-right, so opposite facets pick up opposite colours, and a faint cyan (#63E2FF) rim light behind the object so its edge always separates from the background. - Note for three.js r155 and newer, where this scene will otherwise render as a black silhouette: - A metal has no diffuse response: it only shows what it reflects. With metalness ~0.85 and no environment, point lights alone leave the object invisible. Give the scene an environment: a 2x256 vertical gradient canvas texture, mapped as EquirectangularReflectionMapping, run through PMREMGenerator and assigned to scene.environment. That is a dozen lines and costs almost nothing. - Point-light intensity is now physical and falls off with the square of distance, so values written for older versions render almost black. Scale them up by roughly 50x and keep the ratios between the three lights. - Atmosphere: light exponential fog in the page background colour, subtle enough to soften the far edges without swallowing the object. - Motion: very slow continuous rotation on two axes plus a gentle vertical float. Add cursor parallax: the camera eases a small distance toward the pointer position (lerp it, never snap). - Cap devicePixelRatio at 2, resize with the window, and pause the render loop when the tab is hidden. - Respect prefers-reduced-motion: render one static frame, no rotation, no parallax. - Keep the scene code itself under 3KB. Don't block first paint.
Performance notes
- Technique
- three.js scene
- Scene code
- 3.3 KB
- Library
- three.js, 732 KB
- Over the wire
- 182 KB gzipped
- Device pixel ratio
- Capped at 2
- Reduced motion
- Static frame, no parallax
- Hidden tab
- Render loop paused