Infinite 3D Gallery
Build a high-performance 3D portfolio gallery using Three.js ,GSAP and GLSL shaders. Supports infinite scrolling, smooth navigation, and interactive hover effects.
Full component code is not included—this post provides an overview only. If you face any issues, refer to the working source code provided.
Initializing the project
Start by creating a new Next.js application with TypeScript and install the required dependencies:
Component structure
The gallery is organised into a clean folder structure separating logic, data, shaders, and UI:
Defining project data
Each project contains an image URL, title, year, tags, and a background colour for fallback. We'll use placeholder images from picsum:
Core state & configuration
We define a central state object and configuration that will be shared across the engine. The `state` holds references to Three.js objects, drag flags, offsets, and animation parameters.
Engine initialization & interaction
The `engine.ts` file sets up the Three.js scene, loads textures, creates the shader material, and handles drag events. It also contains the animation loop that lerps all values. Below are the key parts; the full code is available in the provided source repository.
Texture atlas generation
To avoid the browser's texture limit, we combine all project images and text overlays into two large atlases. The `createTextureAtlas` function draws each image into a grid on a single canvas. The text atlas is generated by rendering the project metadata onto a canvas using the Canvas API. Below are the core functions; full code is in the source.
Custom GLSL shaders
All visual magic happens in the fragment shader. It computes the infinite grid, curvature distortion, cell hashing, hover blur, and blends the image and text atlases. Due to its length, only the key parts are shown here; the complete shader is available in the source repository.
The full shader includes logic for drawing the image card, applying a frosted‑glass blur on hover, overlaying the text atlas, and rendering grid borders. You can find it in the source repository linked above.
Main component & interactive controls
The `index.tsx` component mounts the gallery and provides a simple UI panel to tweak curvature, zoom, and toggle flatten mode. The controls use `setConfig` to update the engine state.
Styling
The container takes full viewport and includes a subtle vignette overlay. The `dragging` class changes the cursor.
Using the component
Import the gallery into any page. Make sure to wrap the component in a client directive if using Next.js App Router.
Wrapping Up
Credits to the original inspiration Phantom.studio . Happy coding!
