072

3D Product Showcase Template

£10

Single-product website template with a real-time three.js glass object over full-bleed video: the bottle refracts the footage and wordmark, follows the cursor and turns through scroll chapters. Worked as a fragrance house; suits skincare, spirits, candles and any product launch.

ScrollTrigger Lenis advanced
5 more details
webgl-shadervideo-playbackscrubscroll-revealload-sequence
3D Product Showcase Template - website template preview

This template reads better at your own screen size than in the frame below:

About this template

A complete single-product website built around two materials at once: live footage and a real-time 3D object. A glass bottle rendered in three.js hangs in the middle of full-bleed video and behaves like glass, so the moving water and the giant wordmark behind it are refracted, split into faint colour at the edges and bent as it turns. It ships as a finished site for Oriel, a small fictional fragrance house on the Atlantic coast, with one scent told in three notes.

Read the full template overview

The hero sells as a still: corner navigation, an oversized serif wordmark across the screen and the bottle dead centre over black-sand surf. Move the pointer and a water-drop lens magnifies the footage under it while the bottle leans towards you; press and hold and the atomiser mists and a ripple runs through the water. Scroll and the stage holds while three chapters pass: each one dissolves the footage into the next clip, turns the bottle a full revolution back to its label and moves the glass tint from clear salt to fig green to cedar amber.

Below the stage the page goes quiet on salt-coloured paper: an atelier split with figures, a formula table with ingredient photographs, a full-bleed coast photograph with a pull quote, a collection section with a size picker, stockists and a footer wordmark. Castoro serif carries every heading; Red Hat Text in tracked capitals carries every label.

Making it yours means three video clips, six photographs, the words on the label and in the wordmark, and a short token block. The chapter tints, words and label text are one settings object at the top of the script. Without WebGL, under reduced motion or with no JavaScript the stage becomes four stacked full-height sections with a composed still and the clips, so nothing is lost.

What's included

12 items
  • Real-time three.js glass bottle with transmission, dispersion and tinted attenuation, refracting the footage and wordmark behind it
  • Full-bleed video stage: three muted, looping clips dissolved into each other in one shader as scroll moves through the chapters
  • Cursor-driven water-drop lens with a chromatic rim, plus a bottle that tilts towards the pointer on a frame-rate independent chase
  • Press-and-hold spray: atomiser mist particles and a ripple through the footage, also on a keyboard-accessible Spray button
  • Sticky scroll stage with three note chapters, a full bottle turn between each, per-chapter glass tint and wordmark
  • Autonomous lens drift on touch devices so phones get a moving, reduced version rather than a dead canvas
  • Designed fallback: composed desktop and portrait stills plus stacked chapter sections for reduced motion, no WebGL, no JavaScript or a blocked CDN
  • Atelier split, formula table with ingredient photographs, full-bleed quote, stockists and a footer wordmark on a quiet paper ground
  • Collection size picker with animated price and silhouette, plus a front-end bag counter and newsletter form
  • Full-screen menu that stops smooth scrolling while open and returns focus on close
  • Optional Lenis smooth scrolling on a shared clock with ScrollTrigger
  • Bundled re-encoded H.264 clips and baked WebP photographs with a regeneration manifest

Perfect for

4 use cases
  • Perfume, skincare and beauty brands launching a hero product
  • Craft gin, spirits and beverage bottles
  • Candle and home fragrance studios
  • Any single-product launch with a physical object and brand footage

How it works

4 sections

Glass that refracts the page

The footage and the wordmark are drawn on a plane behind the bottle rather than in the page, so the glass material can refract them. The bottle itself is built from extruded and turned primitives with a canvas-drawn paper label, so there is no model file to load and every dimension is a number you can change.

Pointer and press

On a mouse the pointer drives a magnifying lens in the footage and a gentle tilt of the bottle; both chase their targets at the same speed on 60Hz and 120Hz screens. Pressing anywhere on the stage, or using the Spray button, releases a short mist from the neck and sends a ring through the water. Touch devices get a slow autonomous drift instead of hover.

Scroll chapters

The stage is a tall section with a sticky frame. Its scroll progress chooses the chapter: the copy for that note fades in, the clip dissolves along a noise edge, the wordmark changes to the note's name and the bottle completes a full turn so its label faces front again when the chapter settles. Only the clips being shown are playing.

Fallbacks that are finished pages

A tiny head script checks for WebGL and reduced motion before first paint. If either fails, or three.js never arrives, the stage renders as four full-height sections: a composed still of the hero and the three chapters over their own footage, with clips held on their poster frames under reduced motion.

Plugins ScrollTrigger
Difficulty Advanced
Smooth scroll Lenis integration
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Questions about this template

What kinds of products does this 3D showcase suit besides perfume?

Anything sold as one beautiful object with a mood behind it: skincare and serums, craft gin and spirits, candles and home fragrance, olive oil, watches or headphones. Oriel is a fictional fragrance house; replace the three clips, the label words and the copy, and change the glass tints to suit your bottle or jar.

Can I use my own product model instead of the built bottle?

Yes. The bottle is a group of simple meshes in one function, so you can swap it for a glTF loaded with three.js's GLTFLoader and keep the same glass material, tilt, turn and mist. The README shows where the group is built and which numbers position and scale it for desktop and portrait screens.

What footage works best behind the glass?

Slow, steady clips with strong texture and contrast: surf, leaf shadows, smoke, fabric, pouring liquid. Glass refracts detail, so a flat or blurry clip makes the bottle look empty. Keep each loop around ten seconds at 1600 pixels wide, muted with no audio track, and encode as H.264 MP4 for a few megabytes per clip.

Is the Add to bag button and the size picker connected to a shop?

No. The size picker updates the displayed price and silhouette, and Add to bag only increments the counter in the header and prints a status message; nothing is saved and there is no checkout. Point the form at Shopify Buy Button, Stripe Payment Links, Snipcart or your own cart to sell for real.

Does the newsletter form in the footer collect addresses?

Not yet. It is a static front end that collects one email address and shows a thank-you message without sending anything. Connect it to Mailchimp, Buttondown, ConvertKit, Formspree or your own endpoint by giving the form an action and removing the demo submit handler described in the README.

How heavy is the page, and how does it behave on phones?

The three clips total about six megabytes and load with the page; photographs are baked WebP under 100KB each. Phones render at a lower pixel ratio without dispersion, replace hover with a slow drift, and place a smaller bottle higher in portrait. Under reduced motion or without WebGL they get the static composed still instead.

Paid template

Purchase to unlock the code.

Buying 3D Product Showcase Template opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects.

£10 Standard license, unlimited projects

Browse free effects

Documentation

Quick Start

Open the folder through any static server (videos and ES modules do not load from file:// in every browser), edit the copy and upload it to any static host. There is no build step.

Two things in index.html are required and must stay where they are:

  1. The head script before the stylesheet. It adds has-js (gates the scroll reveals) and, when the device has WebGL 2 and no reduced-motion preference, gl (switches the stage from stacked sections to the sticky WebGL frame). Both happen before first paint, so neither version flashes.
  2. The import map and module shim at the end of <body>. They load three.js r180 and its RoomEnvironment lighting helper as ES modules, then hand them to assets/script.js with an oriel:three-ready event. If the module fails, the shim removes gl and the fallback shows.

Using It With Your Own Design

Start with the token block at the top of assets/style.css: tide (dark ground), salt and paper (reading grounds), ink, foam and one cedar accent, each with an RGB triple. Then open the ORIEL_STAGE settings object at the top of assets/script.js:

Setting What it does
words Four words drawn behind the bottle: the hero wordmark, then one per chapter
tints Glass tint for the hero and each chapter, as hex colours
label The four lines printed on the bottle's paper label
cap, capFinish Cap shape (block or pebble) and finish (lacquer, white, brass or chrome); add ?cap=brass to the URL to preview a finish
ease How quickly the scroll turn and pointer tilt catch up (per 60Hz frame)
lensRadius Radius of the cursor lens in CSS pixels
dprFine, dprCoarse Pixel-ratio caps for mouse and touch devices; the first performance lever

Keep the data- hooks on elements whose behaviour you want: data-stage, data-stage-frame, data-stage-mount, data-stage-block, data-stage-video, data-stage-index, data-spray, data-hero-fade, data-reveal, data-reveal-group, data-menu*, data-collection, data-silhouette, data-bag-count, data-newsletter. Every section is guarded; delete any section below the stage and the rest still runs.

Sections and Configuration

  • Stage. One hero block and three chapter blocks. Each chapter owns one <video data-stage-video="n">, muted loop playsinline autoplay, with a poster. With WebGL the clips keep playing underneath the canvas as textures and only the ones in view play; without it they are the backgrounds of four stacked sections. The hero's .stage__brand line is visually hidden because the canvas (or the composed still) draws the wordmark; it remains the heading's accessible text. If you replace the still with a picture that has no wordmark, delete that CSS rule.
  • The bottle. Built in buildScene() from an extruded rounded rectangle (body), two cylinders (neck and brass collar), a squashed sphere (stone cap) and a plane with a canvas label. BODY_W, BODY_H, BODY_D, BEVEL and RADIUS set its proportions. To use your own product, load a glTF with three.js's GLTFLoader, add it to the bottle group and reuse the glass material on its glass parts.
  • Pointer and spray. Hover drives the lens and tilt on mouse devices; touch devices get a slow drift. Pressing on the stage (not on a link or button) mists the atomiser and sends a ripple through the footage; the Spray button does the same for keyboard users.
  • Chapter index. The 01 / 02 / 03 links jump to the settled position of each chapter, through Lenis when it is running. It is hidden on the hero and on narrow phones, where each chapter's kicker carries its number.
  • Atelier, Formula, Wearing, Stockists. Plain content. Formula rows are a list; add or remove rows freely.
  • Collection. Native radios carry data-price and data-scale. Changing size animates the price and the CSS bottle silhouette. Add to bag only increments the header counter and prints a message: there is no cart or checkout. Connect a real one (Shopify Buy Button, Stripe Payment Links, Snipcart) by replacing the submit handler in initCollection().
  • Newsletter. A static form that collects one email and shows a thank-you message without sending anything. Give it an action for Mailchimp, Buttondown, ConvertKit or Formspree and delete initNewsletter().
  • Menu. A full-screen overlay; it stops Lenis while open (hence data-lenis-prevent), closes on Escape and returns focus to the Menu button.

Footage and Photographs

Clips are 1920x1080, 24fps, six seconds, with no audio track, cross-faded end to start so they loop without a jump. Fig and cedar ship as a VP9 WebM, listed first because it is a fraction of the size, with an H.264 MP4 fallback; salt ships as MP4 only, because on dense surf H.264 came out both smaller and sharper. Only the hero clip autoplays: the chapter clips are preload="none" and start a chapter before they are needed, so the page does not fetch footage nobody has scrolled to. When you swap a clip, keep that pattern, or drop the WebM <source> and keep the MP4. Slow, textured footage refracts best; flat or blurred clips make the glass look empty. Photographs are baked WebP derivatives listed in assets/img-manifest.json; regenerate with bun scripts/build-template-assets.ts 3d-product-showcase-template, or simply replace the files in assets/img/ at the same sizes.

hero-still.webp and hero-still-portrait.webp are frames rendered from the WebGL stage itself; after changing the bottle or clips, screenshot your own stage with the copy hidden and replace them.

File Source (Pexels licence)
assets/video/salt.mp4 https://www.pexels.com/video/aerial-view-of-waves-crashing-on-black-sand-beach-39296252/
assets/video/fig.webm, .mp4 https://www.pexels.com/video/shadowy-silhouettes-of-leafy-branches-at-dusk-34671612/
assets/video/cedar.webm, .mp4 https://www.pexels.com/video/a-smoke-in-a-dark-room-4320605/
assets/img/atelier.webp https://www.pexels.com/photo/8450352/
assets/img/material-salt.webp https://www.pexels.com/photo/3693292/
assets/img/material-fig.webp https://www.pexels.com/photo/34041533/
assets/img/material-cedar.webp https://www.pexels.com/photo/7906948/
assets/img/wearing.webp https://www.pexels.com/photo/person-on-cliff-during-overcast-4641017/

Palette

One palette. Measured contrast pairs are recorded in the :root comment of assets/style.css. Type over footage sits in the lower third, where the stage scrim is strongest; keep new stage copy there. --cedar is never body text on salt; use --cedar-ink.

Accessibility

Content is real HTML throughout: the stage copy, chapter headings and index are in the document whether or not the canvas exists, and the canvas is aria-hidden. All actions are native links and buttons with visible focus, a skip link leads to the content, and the menu manages focus. The pointer lens and tilt are decorative; the spray has a keyboard button. Under reduced motion the WebGL stage never starts, the clips are held on their poster frames and every reveal is visible. With JavaScript off or the CDN blocked, the stacked stage and the full page render without gates.

Dependencies

GSAP 3.15.0 and ScrollTrigger (compatibility floor GSAP 3.12+), Lenis 1.3.17 (optional), and three.js r180 through the import map. Castoro (regular and italic) and Red Hat Text (400, 500) load from Google Fonts with display=swap. GSAP owns the matchMedia branches, teardown, stage scroll progress, the hero intro, chapter copy transitions, reveals and the collection picker; the three.js loop on gsap.ticker owns every continuous stage value (pointer chase, bottle turn, footage dissolve, mist). If your site already imports three.js, reuse that module in the shim rather than loading a second copy.

Teardown

Call window.gsapContext.revert() before removing the page in a client-routed app. It stops the frame loop, disconnects the observers, disposes every geometry, material and texture, releases the WebGL context, removes the canvas and all owned listeners, destroys the Lenis instance it created and leaves unrelated animations alone.

Files

index.html, assets/style.css, assets/script.js, assets/script.min.js, assets/video/ and assets/img/ make up the deployable site. assets/img-src/ holds poster and still masters for the manifest. thumbnail.html and config.json are catalogue build files.

Browser Support and Performance

The WebGL stage needs WebGL 2 and import maps (current Chrome, Edge, Firefox and Safari). Everything else falls back to the stacked stage. The glass uses three.js transmission, which renders the backdrop a second time each frame; the stage only renders while it is on screen. Lower dprFine first, then set dispersion to 0 in the glass material. The three clips total about six megabytes.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.

Your cart

Your cart is empty

The Vault £99

The Vault library, plus future additions to the library.