A self-contained, dependency-free 3D product viewer for the web, built with three.js. Drag to rotate, scroll to zoom, and swap nine finishes live — metals and faceted crystals rendered in real time in the browser.
This is the viewer that powers the Interactive 3D service at Golden Rock → https://goldenrockadvancements.com/3d/.
- Real-time 3D — orbit, zoom and inspect a product model, not a looping video.
- Live material swap — nine finishes: metals (
MeshStandardMaterial) and crystals with physical transmission (MeshPhysicalMaterial). - Studio lighting — image-based lighting via a PMREM-prefiltered
RoomEnvironment, ACES filmic tone mapping. - Labelled hotspots that track the model as it turns, with auto-spin and a reset view.
- Device-gated for performance — the 3D engine loads only on a capable desktop (fine pointer, ≥900px, WebGL2, not Save-Data). Phones, metered connections and reduced-data users get a clean static fallback and never download the 1.3 MB engine.
- Self-hosted and CSP-clean — external ES modules only, no inline scripts, no CDN, no third-party calls. Works under a strict
script-src 'self'Content-Security-Policy, which is why it's safe to embed in a real site via a same-origin iframe.
ES modules must be served over http:// (opening index.html directly from file:// will block the module imports). From the repo folder:
python3 -m http.server 8000
# then open http://localhost:8000Or just open the live demo (GitHub Pages) linked at the top of this repository.
Best viewed on a desktop browser — on phones you'll see the lightweight static fallback by design.
| Rendering | three.js (r160, vendored — see THIRD_PARTY.md) |
| Materials | MeshStandardMaterial (metals) · MeshPhysicalMaterial with transmission (crystals) |
| Controls | OrbitControls (damped, no pan) |
| Lighting | PMREMGenerator + RoomEnvironment, two directional lights |
| Framework | none — plain ES modules, zero dependencies to install |
| Fonts | self-hosted Cormorant Garamond (OFL) |
index.html the viewer page (inline CSS, device gate + static fallback)
app.js the viewer module (scene, materials, controls, hotspots)
three.module.js three.js r160 (minified, vendored)
OrbitControls.js three.js addon (import rewritten to the local module)
RoomEnvironment.js three.js addon (import rewritten to the local module)
fonts/ Cormorant Garamond woff2
Swapping in a real client product is a matter of replacing the generated geometry with a loaded .glb/.gltf and mapping the finish list to that product's materials.
Built by Tyler Milam / Golden Rock — I build real interactive 3D into client websites (product viewers, live configurators, 3D hero scenes). This repo is a compact, honest example of the approach, extracted from a viewer running in production.
MIT © 2026 Tyler Milam (Golden Rock). Third-party components retain their own licenses — see THIRD_PARTY.md.