A modern, engine-first web application built with Next.js 15, React Three Fiber, and Three.js WebGPU/TSL. Features a persistent 3D canvas across routes, interactive shader experiments, and a comprehensive content system.
- Engine-First Design: Persistent WebGPU canvas across all routes
- Route-Based Scenes: Automatic scene switching based on URL
- TSL-First Shading: Three.js Shading Language for all shader logic
- Zero Config: Components work out-of-the-box with sensible defaults
- Contentlayer Integration: MDX-based blog with type-safe content
- Template System: Reusable article templates with prop validation
- Dynamic Components: Load templates in MDX with full TypeScript support
- Scene Props: Pass parameters from frontmatter to 3D scenes
- Motion.dev: Smooth page transitions and layout animations
- GSAP: Cinematic scroll effects and text reveals
- Stagger Animations: Coordinated element entrance effects
Organized collection of reusable TSL utilities:
- Noise: Simplex, Perlin, Curl (3D/4D), FBM, Turbulence
- Lighting: Ambient, Diffuse, Directional, Fresnel, Hemisphere
- Math: SDF operations, coordinate transforms, easing functions
- Post-FX: Grain, Vignette, Bloom, LCD, Canvas Weave
- Utils: Color palettes, tonemapping, aspect utilities
- Tweakpane Integration: Auto-generated UI from Zod schemas
- Live Controls: Real-time scene parameter adjustment
- Presets: Save/load configuration presets
- Dev Tools: FPS monitoring, debug visualization
Framework: Next.js 15 (App Router) + React 19 + TypeScript 3D Engine: React Three Fiber + Three.js r180 (WebGPU) Animation: Motion.dev + GSAP Content: Contentlayer (MDX) State: Zustand Styling: Tailwind CSS Admin: Tweakpane + Zod src/ โโโ app/ # Next.js app router โ โโโ layout.tsx # Root layout with persistent canvas โ โโโ page.tsx # Home page โ โโโ blog/ # Blog routes โ โ โโโ page.tsx # Blog listing โ โ โโโ [slug]/ # Individual posts โ โโโ labs/ # Experiments โ โโโ admin/ # Admin dashboard โโโ components/ โ โโโ canvas/ # WebGPU canvas components โ โ โโโ WebGPUScene.tsx โ โ โโโ WebGPUSketch.tsx โ โ โโโ ColorCorrection.tsx โ โโโ motion/ # Animation components โ โ โโโ PageTransition.tsx โ โ โโโ ScrollEffects.tsx โ โโโ templates/ # Article templates โ โโโ registry.ts โ โโโ ShaderHero.tsx โ โโโ Floating3D.tsx โ โโโ TemplateLoader.tsx โโโ lib/ โ โโโ tsl/ # TSL utilities library โ โ โโโ noise/ โ โ โโโ lighting/ โ โ โโโ math/ โ โ โโโ postfx/ โ โ โโโ utils/ โ โโโ store.ts # Zustand state โ โโโ scenes.ts # Scene resolver โ โโโ utils.ts # Helper functions โ โโโ admin/ # Admin utilities โ โโโ schemas.ts โ โโโ pane.ts โโโ scenes/ # Per-route 3D scenes โ โโโ home/ โ โโโ portfolio/ โโโ content/ # MDX content โโโ posts/ - Node.js 18+
- npm/pnpm/yarn
- Browser with WebGPU support (Chrome/Edge 113+)
# Install dependencies npm install # Start development server npm run dev # Build for production npm run build # Start production server npm startVisit http://localhost:3000 to see the site.
- Home:
/- Landing page with features - Blog:
/blog- Article listing - Labs:
/labs- Experiments (coming soon) - Admin:
/admin- Control dashboard
Create MDX files in content/posts/:
--- title: "My Article" summary: "Article description" publishedAt: "2025-01-20" slug: "my-article" templateId: "shader-hero" sceneProps: shaderType: "noise" intensity: 1.5 tags: ["webgpu", "tsl"] featured: true --- Your content here...Use templates in MDX:
import { TemplateLoader } from '@/components/templates/TemplateLoader' <TemplateLoader templateId="shader-hero" props={{ title: "Hello WebGPU", subtitle: "Subtitle here", shaderType: "noise", intensity: 1.5 }} />- Create component in
src/components/templates/ - Define Zod schema for props
- Register with
registerTemplate() - Use in MDX with
TemplateLoader
Access at /admin to control:
- Creative Mode: Colors, effects, motion parameters
- Dev Mode: Renderer settings, debug tools, performance
- Presets: Save/load configurations
- Export: Download config as JSON
import { simplexNoise3d, cosinePalette } from '@/lib/tsl' import { Fn, vec3 } from 'three/tsl' const myShader = Fn(() => { const noise = simplexNoise3d(position.mul(scale)) const color = cosinePalette(noise, colorA, colorB, colorC, colorD) return vec3(color) })Scenes automatically resolve based on route:
// lib/scenes.ts const sceneMap = { '/': HomeScene, '/portfolio': PortfolioScene, '/blog': HomeScene, // Fallback }Create scenes in src/scenes/[name]/Scene.tsx:
export function HomeScene() { const params = useStore((state) => state.params) return ( <> <mesh> <boxGeometry /> <meshStandardMaterial color={params.colorPrimary} /> </mesh> </> ) }Each TSL utility is self-contained with no external config required.
Admin controls auto-generate from Zod schemas.
Templates register themselves on import.
3D content automatically switches with navigation.
- React 19 peer dependency warnings with some packages (safe to ignore)
- shadcn/ui components need manual installation due to React 19
- Contentlayer needs rehype/remark plugins installed separately
- Some TSL files have linter warnings (intentional for generated code)
- Additional templates (ParticleScroll, CodePlayground, Gallery3D)
- Lab experiments (GPU particles, fluid simulation, shader playground)
- OpenAI AgentKit integration (UX Assistant + Builder Agent)
- Sanity CMS for portfolio content
- Cloudflare Pages deployment
- Pagefind search integration
- Compute shader examples
MIT
Built with patterns from:
- Fragments Boilerplate - WebGPU canvas pattern
- Portfolio Main - TSL utilities organization
- Maxime Heckel Blog - Content patterns