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