| 🏅 Achievement | 📌 Detail |
|---|---|
| 🔥 Officially Reposted by Three.js | Featured directly by the official Three.js account — recognized by the core WebGL community as a standout real-world implementation |
| 👍 190+ Likes on LinkedIn | Organically reached 190+ reactions on LinkedIn, driving significant professional engagement across the web & 3D development community |
Being officially featured by Three.js — the foundational library powering this entire project — is a rare honor that validates the depth of the WebGL engineering involved. The LinkedIn reception confirms real-world interest from both technical and business audiences.
PorscheLab is a photorealistic, browser-native 3D car configurator that brings dealership-grade automotive visualization directly into any web browser — no app download, no plugins, no compromise.
Built entirely by hand with 0% AI-generated code, every line of this codebase reflects intentional engineering decisions — from handcrafted 6-DOF camera keyframe arrays per vehicle, to a 13-channel audio engine that responds to every user interaction in real time.
Business Value: In an era where automotive brands compete fiercely for customer attention online, PorscheLab demonstrates what a next-generation digital showroom looks like — immersive, interactive, and accessible from any device at 60–120 FPS, including mobile.
PorscheLab is more than a technical showcase. It represents a digital-first sales and engagement model for the premium automotive industry:
| Business Use Case | How PorscheLab Enables It |
|---|---|
| 🏪 Virtual Dealership | Customers explore any model, any angle, any color — without stepping into a showroom |
| 🎨 Real-Time Personalization | Live paint, metalness & roughness controls let buyers configure their dream car instantly |
| 📱 Omnichannel Reach | Full mobile support means the configurator works on any device, anywhere |
| 🌍 Environment Storytelling | 8 cinematic HDRI environments let brands present cars in aspirational contexts |
| 🔊 Sensory Brand Experience | Spatial audio tied to every interaction (door, engine, spray) reinforces emotional connection |
| 🏠 Interior Deep-Dive | Buyers can step inside any car, switch seats, and inspect the cockpit — virtually |
| 📊 Model Comparison | Switch between 7 distinct Porsche lineups in seconds with seamless cinematic transitions |
| 🔗 Embedded Spec Sheet | Right-panel iframe links directly to official Porsche product pages per model |
┌─────────────────────────────────────────────────────────────┐
│ 🤖 AI-Generated Code → 0% (fully handcrafted) │
│ 🎮 Rendering Performance → 60–120+ FPS │
│ 📱 Mobile Support → 100% (touch, pinch, UI) │
│ 🏎️ Porsche Models Included → 7 photorealistic models │
│ 🎨 Color Configurations → 16 presets + custom hex │
│ 🌅 HDRI Environments → 8 cinematic scenes │
│ 🔊 Audio Channels → 13 spatially-aware sounds│
│ 🏆 Lighthouse Score → 100 across all metrics │
└─────────────────────────────────────────────────────────────┘
The moment a user lands on PorscheLab, they're greeted with a cinematic loading sequence followed by a scroll-driven brand narrative — immersing them into Porsche's history before they ever touch the configurator.
PorscheLab is also engineered to perform at the highest standard — achieving 100/100 across all Lighthouse metrics (Performance · Accessibility · Best Practices · SEO), proving that stunning 3D experiences and web performance are not mutually exclusive.
See the cover images above for the full-screen brand experience and UX/UI overview.
Users aren't passive observers. PorscheLab hands total physical control of the camera — drag to orbit, pinch to zoom, tap the inspect icon to jump to pre-choreographed cinematic viewpoints. Every angle, every detail.
The user can freely orbit around the vehicle in full 3D. The color picker panel is open at the bottom — 16 curated Porsche paint colors + custom hex input with live PBR paint update.
One click on a color swatch triggers a GSAP-animated smooth color transition directly on the car's PBR material in the WebGL scene — no page reload, no delay. The spray-shake sound fires simultaneously for full sensory feedback.
New paint color applied in real time. Metalness and roughness sliders allow further surface customization — from matte to mirror-chrome — all bound to per-car Zustand state.
Because every model is a fully realized 3D asset with complete geometry on all sides, users can navigate to the rear of the vehicle — demonstrating that this is genuine spatial content, not a billboard or turntable illusion.
Rear-view perspective accessed via the Exterior Inspect cycling button. Each of the 8 keyframe positions is hand-calibrated per model for the most flattering camera angle.
A single tap on the steering wheel icon triggers the door-close sound effect, locks the camera into interior mode, and begins a guided cockpit tour. The camera constraints change entirely — close-range, restricted orbit, designed to feel like you're sitting in the seat.
Interior inspection mode active. Camera constraints shift to micro-range (minDistance: 0.05) to simulate being seated inside the vehicle. Interior ambient audio plays automatically.
The environment panel gives users access to 8 real-world HDRI captures streamed live from Polyhaven at resolution-optimized quality (2K on mobile, 4K on desktop). The environment changes the entire lighting of the scene — affecting reflections, shadows, and mood.
Environment panel open showing all 8 HDRI options with thumbnail previews. Each environment has individually tuned ground projection parameters for interior vs. exterior views.
The left hamburger menu reveals a model information panel displaying the car's real-world specifications — 0-100 km/h time, top speed, power output (kW + PS), and price. A direct link to the official Porsche product page is embedded as an iframe.
Model detail drawer open. Specs pulled from the Zustand
porscheModelListstore. The iframe at the bottom loads the live Porsche Thailand product page for the current model.
Interior mode isn't limited to the driver's seat. Users can cycle through up to 5 interior camera positions per vehicle — including rear passenger seats — for a full cabin inspection experience.
Rear cabin perspective. The interior inspect mode cycles through 5 hand-placed camera keyframes, each giving a distinct spatial understanding of the vehicle's interior layout.
Same interior inspection applied to a different Porsche model — demonstrating that every vehicle in the lineup has independently configured interior camera paths.
The change-car panel displays all available Porsche models with thumbnail previews. Selecting a model triggers a lazy-load swap — the old model unmounts, the new GLTF component is code-split imported and rendered, with camera position restored to the hero exterior view.
Model selection panel showing all 7 Porsche models. Each entry displays real performance data. Switching models is seamless — Zustand state resets all inspect modes automatically.
PorscheLab covers Porsche's complete current-era lineup — from EV to hypercar. Every model has been manually optimized with calibrated PBR material parameters to look photorealistic under any HDRI environment.
All 7 models share the same camera system, audio engine, and UI — but each has independently calibrated metalness/roughness values, camera keyframe sets, and interior configurations.
Every interaction — touch-to-orbit, pinch-to-zoom, tap-to-inspect, color swatches, spec panels — works identically on mobile. HDRI resolution auto-scales to 2K on smaller viewports. FPS stays at 60–120 even on mid-range phones.
Mobile screenshot composite showing smooth real-time rendering on phone screens. Touch controls mirror desktop interactions. The responsive layout adapts camera FOV (65° on mobile vs 50° on desktop) for optimal framing.
- Technical Project Overview
- Technology Architecture
- System Architecture Diagram
- Rendering Pipeline
- Scene Initialization Sequence
- State Management Architecture
- Camera Control System
- Audio Engine Architecture
- 3D Model Pipeline
- Homepage Scroll Animation System
- Configurator UI Layer
- HDR Environment System
- Deployment Pipeline
- Project Structure
- Getting Started
- Performance Considerations
PorscheLab tackles several notoriously difficult engineering challenges simultaneously:
| Challenge | Solution |
|---|---|
| High-polygon GLTF models (multiple) in browser | Lazy-loaded Suspense with per-car code splitting |
| Physically-based rendering at 60fps | Tuned PBR material params + low-res post-process passes |
| Cinematic camera fly-throughs without jank | GSAP timeline-driven CameraControls choreography |
| Seamless exterior ↔ interior camera transitions | Per-model 3D LookAt keyframe configs stored in Zustand |
| Immersive spatial audio that mirrors scene state | Pre-loaded 13-track Web Audio engine with state gating |
| Scroll-driven homepage narrative with pinned sections | GSAP ScrollTrigger + SplitText word-by-word reveals |
| Real-time PBR paint override with metalness/roughness | Per-car MeshStandardMaterial binding through Zustand |
| HDR environment switching (8 environments) | Dynamic .hdr streaming from Polyhaven CDN |
Deployed on Netlify with SPA redirect rules and Node 24 build environment.
┌─────────────────────────────────────────────────────────────────────┐
│ PorscheLab Stack │
├──────────────────┬──────────────────────────────────────────────────┤
│ Presentation │ React 19 + TypeScript 5.8 + React Router 7 │
│ 3D Engine │ Three.js r176 + React Three Fiber 9 │
│ 3D Utilities │ @react-three/drei (CameraControls, Environment, │
│ │ AccumulativeShadows, useProgress) │
│ Post-Processing │ @react-three/postprocessing + postprocessing │
│ │ (Bloom, Vignette, BlendFunction) │
│ Animation │ GSAP 3 + @gsap/react + ScrollTrigger + SplitText│
│ │ + TextPlugin │
│ State │ Zustand 5 (3 independent stores) │
│ Audio │ Web Audio API (HTMLAudioElement, 13 tracks) │
│ 3D Assets │ GLTF/GLB (gltfjsx-generated React components) │
│ Build │ Vite 6 (ESM, code-splitting, lazy imports) │
│ Deploy │ Netlify (Node 24, SPA redirects) │
└──────────────────┴──────────────────────────────────────────────────┘
graph TD
A["🌐 Browser Entry: main.tsx"]:::entry --> B["BrowserRouter"]
B --> C["Route: / → Homepage"]
B --> D["Route: /configurator → ProtectedPorscheConfigurator"]
B --> E["Route: * → Redirect /"]
C --> F["Homepage.tsx"]
F --> G["HomepageMain.tsx (lazy)"]
G --> H["Loading Screen\n(4-layer slide-out animation)"]
G --> I["NavigateBar.tsx"]
G --> J["HomepageContent"]
J --> J1["HomepageHero\n(Video BG)"]
J --> J2["HomepageHistorySection\n(GSAP Pin + SplitText)"]
J --> J3["HomepagePresentSection\n(Parallax Image Reveal)"]
J --> J4["HomepageChooseCar\n(Model Picker Grid)"]
G --> K["InitLogic.tsx\n(GSAP ScrollTrigger Orchestrator)"]
D --> L["ProtectedPorscheConfigurator.tsx\n(Route Guard)"]
L --> M["PorscheConfigurator.tsx\n(Main 3D Scene)"]
M --> N["NavigateBarConfigurator.tsx\n(2D UI Overlay)"]
M --> O["R3F Canvas"]
O --> P["CameraControls\n(@react-three/drei)"]
O --> Q["DynamicCarChanging.tsx\n(Lazy Model Switcher)"]
O --> R["MemoLighterAccumulativeShadows\n(Shadow Baking)"]
O --> S["Environment\n(HDR Streaming)"]
O --> T["InitialConfiguratorLogics.tsx\n(Camera Choreography)"]
O --> U["EffectComposer\n(Bloom + Vignette)"]
M --> V["LoadingHomeScreen.tsx\n(Overlay + Progress)"]
M --> W["InitLogicNavConfig.tsx\n(2D UI Entrance Animation)"]
subgraph STORES ["⚙️ Zustand State Stores"]
X["usePorscheConfiguratorSettings\n• 7 car configs\n• PBR material params\n• Camera keyframes\n• Color palettes\n• 8 HDRI environments\n• UI flags"]
Y["usePorscheSoundSettings\n• 13 Audio channels\n• Playback state flags\n• Preloaded Audio nodes"]
Z["useSceneSettings\n• Camera control flags\n• Animation played flags\n• CameraControls mode"]
end
N --> X
N --> Y
T --> X
T --> Y
T --> Z
Q --> X
K --> X
classDef entry fill:#1a1a2e,color:#fff,stroke:#7c3aed
classDef store fill:#0f3460,color:#fff,stroke:#0ea5e9
flowchart LR
A["GLTF Model\n(gltfjsx component)"] --> B["MeshStandardMaterial\n(PBR)"]
B --> C["Color Uniform\n(Zustand currentPorscheColor)"]
B --> D["Metalness Uniform\n(per-car Zustand value)"]
B --> E["Roughness Uniform\n(per-car Zustand value)"]
F["Environment.hdr\n(Polyhaven CDN stream)"] --> G["IBL\n(Image-Based Lighting)"]
G --> B
H["AccumulativeShadows\n(SoftShadow baking)"] --> I["Ground Contact Shadow\n(Shadow Plane)"]
B --> J["WebGL Render Pass"]
I --> J
G --> J
J --> K["EffectComposer"]
K --> L["BloomEffect\n(intensity: 0.24\nkernelSize: 1\nluminanceThreshold: 0.0\nmipmapBlur: true\nresolution: 64×64)"]
L --> M["VignetteEffect\n(offset: 0.5\ndarkness: 0.5\nblend: NORMAL)"]
M --> N["🖥️ Canvas Output"]
This is the most critical orchestration in the entire application. The configurator scene boots in 4 strict sequential phases to prevent race conditions between asset loading, shadow baking, and camera choreography:
sequenceDiagram
participant U as User
participant A as App
participant DC as DynamicCarChanging
participant ACC as AccumulativeShadows
participant ICL as InitialConfiguratorLogics
participant UI as InitLogicNavConfig
participant SND as AudioEngine
U->>A: Navigate to /configurator
A->>DC: Mount DynamicCarChanging (Suspense)
Note over DC: Lazy-import GLTF component for currentCar
DC-->>A: setRenderedCar(true) ✅ Phase 1 Complete
A->>ACC: Mount MemoLighterAccumulativeShadows
Note over ACC: Progressive shadow baking begins
ACC-->>A: setRenderedAccumulativeShadow(true) ✅ Phase 2 Complete
A->>ICL: Mount InitialConfiguratorLogics (gated on renderedAccumulativeShadow)
ICL->>ICL: Check playedInitialConfiguratorAnimation
alt First Visit
ICL->>ICL: Run 5-step cinematic camera timeline (GSAP)
Note over ICL: Step 1: Rear approach<br/>Step 2: Side sweep<br/>Step 3: Rear pan<br/>Step 4: Detail zoom-in<br/>Step 5: Final hero position
ICL->>SND: playLogoSound() @ t+500ms
ICL->>SND: playInitialSound() + playMusic() @ t+1500ms
else Return Visit
ICL->>ICL: setLookAt() to saved hero position instantly
end
ICL-->>A: setStartedScene(true) ✅ Phase 3 Complete
A->>UI: Mount InitLogicNavConfig (gated on startedScene)
UI->>UI: GSAP entrance animations for 2D UI elements
Note over UI: Nav bar, menu icons, overlays fade in
UI-->>U: ✅ Phase 4 Complete — Scene Interactive
Three specialized Zustand stores isolate concerns with zero cross-store coupling:
graph LR
subgraph STORE1 ["usePorscheConfiguratorSettings (672 lines)"]
direction TB
S1A["Scene Flags\n• renderedCar\n• renderedAccumulativeShadow\n• startedScene\n• beenToHomepage"]
S1B["Car Selection\n• currentCar (0-6)\n• porscheModelList[7]\n• porscheListConfigs[7]"]
S1C["PBR Material\n• metalness per model\n• roughness per model\n• currentPorscheColor\n• porscheColorLists[16]"]
S1D["Camera Presets\n• exterior[8] keyframes per car\n• interior[5] keyframes per car\n• interiorOrNot\n• exteriorInspectMode\n• interiorInspectMode"]
S1E["Environment\n• environments[8]\n• currentEnvironmentIndex\n• HDR path + intensity\n• ground params (interior/exterior)"]
S1F["UI State\n• leftSideMenu\n• drawerIframe\n• currentDrawer\n• sprayStatus\n• turnOnHeadLight"]
end
subgraph STORE2 ["usePorscheSoundSettings (213 lines)"]
direction TB
S2A["Preloaded Tracks\n• 13 HTMLAudioElement instances\n• All preloaded on module eval"]
S2B["Playback State Flags\n• playedInitialSound\n• playedDoorCloseSound\n• playedInteriorSound\n• playedEnvironmentSound\n• playedMusic"]
S2C["Play/Stop Actions\n• Door open/close\n• Initial engine\n• Interior ambience\n• Logo sting\n• Environment\n• Background music\n• UI SFX (click/hover/back)\n• Paint SFX (shake/change/finish)"]
end
subgraph STORE3 ["useSceneSettings (small)"]
direction TB
S3A["CameraControls Ref State\n• configuratorCameraControlsStore\n• toggleConfiguratorCameraControls()"]
S3B["Animation State\n• playedInitialConfiguratorAnimation\n• playedInitialHomeAnimation\n• togglePlayedInitialConfiguratorAnimation()"]
S3C["Mode Flags\n• configuratorCameraControlsMode\n• toggleConfiguratorCameraControlsMode()"]
end
The camera system is one of the most intricate parts of PorscheLab. It uses @react-three/drei's CameraControls with handcrafted 6-DOF keyframe arrays stored per model.
flowchart TD
A["User Action\n(UI Button Click)"] --> B{Check Mode}
B --> C["Exterior Inspect Mode\nexteriorInspectMode: 0-7"]
B --> D["Interior Mode\ninteriorOrNot: true"]
B --> E["Free Orbit\n(CameraControls enabled)"]
C --> F["Read from Store:\nporscheListConfigs[currentCar].exterior[exteriorInspectMode]\n= [posX, posY, posZ, targetX, targetY, targetZ, transition]"]
D --> G["Read from Store:\nporscheListConfigs[currentCar].interior[interiorInspectMode]\n= [posX, posY, posZ, targetX, targetY, targetZ, transition]\n\nConstraints:\n• smoothTime: 0.3 (fast)\n• maxPolarAngle: PI/1.5\n• minDistance: 0.05\n• maxDistance: 0.1"]
E --> H["Mouse: Rotate / Dolly\nTouch: RotateTouch / DollyTouch\n\nConstraints:\n• smoothTime: 1.0 (slow)\n• maxPolarAngle: PI/2 (no flip)\n• minDistance: 2.8\n• maxDistance: 5"]
F --> I["cameraControlsRef.current?.setLookAt(..., animate)"]
G --> I
H --> I
I --> J["Three.js CameraControls\nInterpolates per-frame"]
J --> K["🖥️ Rendered View"]
subgraph INTERIOR_SFX ["Side Effects"]
L["playDoorCloseSound()"]
M["playInteriorSound()"]
N["playDoorOpenSound() on exit"]
end
D --> L
D --> M
B --> N
graph TD
INIT["Module Evaluation\n(usePorscheSoundSettings.tsx)"]
INIT --> T1["soundDoorClose\nporsche_door_close.mp3\nvol: 0.2"]
INIT --> T2["soundDoorOpen\nporsche_door_open.mp3\nvol: 0.2"]
INIT --> T3["soundPorscheConfigStart\nporsche_configurator_start.mp3\nvol: 0.2"]
INIT --> T4["soundPorscheConfigInterior\nporsche_configurator_interior.mp3\nvol: 0.2"]
INIT --> T5["soundPorscheLogo\nporsche_logo_sound.mp3\nvol: 0.2"]
INIT --> T6["soundEnvironment\nporsche_environment.mp3\nvol: 0.2"]
INIT --> T7["soundMusic\nwaves-to-particles.mp3\nvol: 0.2 | loop: true"]
INIT --> T8["clickButton\nbutton-click.mp3\nvol: 0.2"]
INIT --> T9["backButton\nbutton-back.mp3\nvol: 0.2"]
INIT --> T10["hoverButton\nbutton-hover.mp3\nvol: 0.2"]
INIT --> T11["colorInputChange\ncolor-input-change.mp3\nvol: 0.05"]
INIT --> T12["colorInputChangeFinished\ncolor-input-change-finished.mp3\nvol: 0.05"]
INIT --> T13["shakingSpray\nshake-spray.mp3\nvol: 0.2"]
subgraph GATE ["State-Gated Playback (Zustand flags)"]
G1["playedInitialSound → play once on first configurator mount"]
G2["playedDoorCloseSound → play once per interior entry session"]
G3["playedInteriorSound → play once per interior visit"]
G4["playedEnvironmentSound → play once per environment panel open"]
end
T3 --> G1
T1 --> G2
T4 --> G3
T6 --> G4
Each Porsche model goes through a specialized asset pipeline before appearing in the browser:
flowchart LR
A["Original .GLB\n(Blender / Source)"] --> B["gltfjsx CLI\n(@react-three/gltfjsx)"]
B --> C["Auto-generated TSX Component\n(typed nodes, materials, animations)"]
C --> D["Manual PBR Binding\n• Inject Zustand metalness\n• Inject Zustand roughness\n• Inject Zustand color\n• Wire headlight emission toggle\n• Calibrate per-mesh material params"]
D --> E["Lazy Import Wrapper\n(DynamicCarChanging.tsx)"]
E --> F["Code Split Chunk\n(Vite build output)"]
F --> G["Suspense boundary\n(null fallback, invisible load)"]
G --> H["🖥️ Rendered in WebGL Scene"]
subgraph MODELS ["7 Models — Individual Chunk Sizes"]
M1["PorscheSpyder.tsx\n~196KB source"]
M2["Porsche911GT3RS.tsx\n~176KB source"]
M3["PorscheTaycan.tsx\n~78KB source"]
M4["PorschePanamera.tsx\n~96KB source"]
M5["Porsche911TurboS.tsx\n~44KB source"]
M6["PorscheCayenne.tsx\n~16KB source"]
M7["PorscheCayman.tsx\n~14KB source"]
end
The homepage features a multi-chapter GSAP ScrollTrigger narrative with over 30 individual animation directives, pinned sections, and reactive text swapping:
sequenceDiagram
participant S as ScrollPosition
participant G as GSAP ScrollTrigger
participant D as DOM
S->>G: homepageHero bottom hits viewport bottom
G->>D: Fade + blur homepageHero (opacity 0, blur 5px)
G->>D: Transition background: black → white
S->>G: aboutContainer enters viewport
G->>D: aboutText1 parallax (y: -700 → 250)
G->>D: aboutImage1 reveal (opacity 0 → 1, y: -500 → 250)
G->>D: innerAboutImage1 expand (width: 90% → 100%)
S->>G: aboutContainer2 enters
G->>D: aboutContainer2 fade up
G->>D: aboutText2 slide up reveal
G->>D: aboutVideo parallax y shift
S->>G: about__video center hits bottom
G->>D: Expand aboutVideo to 100vw × 100vh
G->>D: Background: white → black
S->>G: historySection__headLine enters
G->>D: SplitText word-by-word stagger reveal
G->>D: historySection__historyHR width: 0 → 100%
G->>D: about__video fade out
Note over G,D: PIN historySection__explaination for 4000px of scroll
loop For each of 6 history timeline entries
S->>G: historyImage[n] enters viewport (top 70%)
G->>D: Image zoom (width → 60%) + blur out
G->>D: Swap title text with GSAP TextPlugin
G->>D: Swap description text with GSAP TextPlugin
end
G->>D: historySection__historyContainer fade out
S->>G: historyPresent__container enters
G->>D: presentEraImg fade in
G->>D: presentEraLogo brightness invert
Note over G,D: PIN historyPresent__container for 3000px
S->>G: chooseCar__container enters
G->>D: historyPresent fade out + blur(5px)
G->>D: chooseCar__openingMessage color reveal
G->>D: chooseCar__carList opacity reveal
graph TD
NAV["NavigateBarConfigurator.tsx"]
NAV --> TOP["Top Navigation Bar"]
TOP --> TL["Hamburger → Model Detail\n(toggleLeftSideMenu)"]
TOP --> TC["Porsche Logo + Model Name Logo\n(per-car dynamic icon)"]
TOP --> TR["Right Icon Menu\n(6 icons)"]
TR --> I1["🎨 Spray\n→ Toggle color picker panel"]
TR --> I2["🚗 Front Car\n→ Cycle exterior keyframes"]
TR --> I3["🏎️ Steering Wheel\n→ Enter interior mode\n+ play door close SFX"]
TR --> I4["🌄 Environment\n→ Open HDRI selector\n+ play environment SFX"]
TR --> I5["🔄 Change Car\n→ Open car switcher panel"]
TR --> I6["💡 Headlight\n→ toggleHeadLight()"]
NAV --> BOTTOM["Bottom Action Bar"]
BOTTOM --> BC["Color Picker\n• input[type=color] → setCurrentPorscheColor\n• 16 preset swatches\n• GSAP smooth color transition\n• Spray shake SFX"]
BOTTOM --> BS["Surface Controls\n• Roughness slider (0-1)\n• Metalness slider (0-1)\n• Per-model state in Zustand"]
BOTTOM --> BB["Back Button\n→ Stop all audio\n→ navigate('/')"]
NAV --> LEFT["Left Slide Panel\n(PorscheConfiguratorLeftMenu)\n• Model Detail accordion"]
NAV --> RIGHT["Right Drawer Panel\n(PorscheConfiguratorRightMenuPages)\n• Dynamic content per icon\n• GSAP slide-in transition"]
NAV --> OVL["navigateConfig__overlay\n(GSAP backdrop-filter blur\nduring model loading)"]
graph LR
subgraph CONFIG ["Environment Config (per entry)"]
N["name: string"]
IMG["image: /images/environments/...webp\n(thumbnail)"]
PATH["environmentPath: polyhaven CDN URL\n(resolution: 2k|4k based on viewport width)"]
EI["environmentIntensity: number"]
EG["envGround: height/radius/scale\n(exterior view)"]
EGI["envGroundInterior: height/radius/scale\n(interior view)"]
end
subgraph RES ["Resolution Selection (on module load)"]
W["window.innerWidth < 1100"] --> R2K["resolution = '2k'\n(performance)"]
W --> R4K["resolution = '4k'\n(quality)"]
end
subgraph ENVLIST ["8 Environments Available"]
E1["Forest Path\n(tief_etz)"]
E2["Victoria Sunset"]
E3["Overcast Soil"]
E4["Abandoned Lot\n(lot_02)"]
E5["Rural Winter Roadside"]
E6["Zawiszy Czarnego"]
E7["Small Rural Road"]
E8["Zwartkops Start Sunset"]
end
PATH --> DREI["@react-three/drei Environment\nfiles={environmentPath}\nenvironmentIntensity={...}\nground={interiorOrNot ? envGroundInterior : envGround}"]
DREI --> IBL["IBL Applied to all PBR materials in scene"]
flowchart LR
A["Developer\ngit push"] --> B["Netlify CI"]
B --> C["Install Node 24"]
C --> D["cd client/\nnpm install"]
D --> E["tsc -b (TypeScript check)"]
E --> F["vite build\n(ESM + code splitting)"]
F --> G["dist/ output\n• Per-car lazy chunks\n• Asset hashing\n• Compressed bundles"]
G --> H["Netlify CDN\nEdge distribution"]
H --> I["SPA Redirect rule\n/* → /index.html : 200\n(client-side routing)"]
I --> J["🌐 Live Site"]
PorscheLab/
├── netlify.toml # Netlify build config + SPA redirect
└── client/
├── package.json # Dependencies manifest
├── vite.config.ts # Vite build config
├── tsconfig.json # TypeScript project references
├── index.html # Entry HTML + meta tags
└── src/
├── main.tsx # App root: Router + lazy page imports
├── index.css # Global reset + CSS custom properties
├── pages/
│ ├── Homepage.tsx # Homepage page + loading screen
│ ├── PorscheConfigurator.tsx # Main 3D scene orchestrator
│ └── ProtectedPorscheConfigurator.tsx # Route guard wrapper
├── Components/
│ ├── Logics/
│ │ ├── InitLogic.tsx # Homepage GSAP ScrollTrigger orchestrator
│ │ ├── InitLogicNavConfig.tsx # Configurator 2D UI entrance animations
│ │ ├── InitialConfiguratorLogics.tsx # 3D camera cinematic sequence
│ │ └── HeroContentFrameUpdater.tsx # Hero frame sync utility
│ ├── SceneObjects/
│ │ ├── DynamicCarChanging.tsx # Lazy model switcher
│ │ ├── Porsche911GT3RS.tsx # gltfjsx PBR component (176KB)
│ │ ├── PorscheSpyder.tsx # gltfjsx PBR component (196KB)
│ │ ├── PorscheTaycan.tsx # gltfjsx PBR component (78KB)
│ │ ├── PorschePanamera.tsx # gltfjsx PBR component (96KB)
│ │ ├── Porsche911TurboS.tsx # gltfjsx PBR component (44KB)
│ │ ├── PorscheCayenne.tsx # gltfjsx PBR component (16KB)
│ │ ├── PorscheCayman.tsx # gltfjsx PBR component (14KB)
│ │ └── Light/
│ │ └── MemoLighterAccumulativeShadows.tsx
│ ├── Post-processing/
│ │ └── EffectComposerHero.tsx # Bloom + Vignette composer
│ └── UI/
│ ├── NavigateBarConfigurator.tsx # Full configurator UI overlay (497 lines)
│ ├── NavigateBar.tsx # Homepage navigation
│ ├── HomepageMain.tsx # Homepage layout root
│ ├── HomepageContent.tsx # Hero + sections container
│ ├── HomepageHistorySection.tsx # 6-chapter scroll history
│ ├── HomepagePresentSection.tsx # Present era pinned section
│ ├── HomepageLeftMenu.tsx # Homepage sidebar nav
│ ├── HomepageFooter.tsx # Footer component
│ ├── HomepageVideoClicking.tsx # Video popup trigger
│ ├── VideoPopupComponent.tsx # Modal video player
│ ├── TransitionToConfigurator.tsx # Page transition handler
│ ├── PorscheConfiguratorLeftMenu.tsx # Model detail left panel
│ ├── PorscheConfiguratorRightMenuPages.tsx # Dynamic right panel
│ ├── LoadingScreen/
│ │ └── LoadingHomeScreen.tsx # WebGL asset load overlay
│ └── Skeletons/
├── stores/
│ ├── usePorscheConfiguratorSettings.tsx # Primary state store (672 lines)
│ ├── usePorscheSoundSettings.tsx # 13-channel audio engine (213 lines)
│ ├── useSceneSettings.tsx # Camera + animation flags
│ └── useCameraControls.tsx # CameraControls ref store
├── styles/
│ ├── canvas.css
│ ├── nav.css
│ ├── loadingScreen.css
│ ├── fonts/
│ └── components/ + pages/
├── types/
│ ├── porscheConfigType.ts
│ └── environemtnConfigType.ts
├── utils/
│ └── gsapColorSmoothChange.ts # GSAP-driven PBR color transition util
└── statics/
└── (static data / constants)
- Node.js ≥ 18 (24 recommended, matches Netlify)
- npm ≥ 9
# Clone repository
git clone https://github.com/yourusername/PorscheLab.git
cd PorscheLab/client
# Install dependencies
npm installnpm run dev
# → http://localhost:5173npm run build
# Output: client/dist/tsc -b --noEmitnpm run lint| Strategy | Implementation |
|---|---|
| Lazy model loading | Each of 7 car models is a separate Vite code-split chunk, loaded only when selected |
| Suspense boundaries | null fallback prevents layout shifts during model swaps |
| Resolution-adaptive HDR | 2K HDRIs on viewports < 1100px, 4K on desktop |
| Bloom at 64×64 | Post-processing resolve at 64px to minimize GPU memory bandwidth |
| Memoized shadows | MemoLighterAccumulativeShadows wrapped in React.memo to prevent re-baking |
| Audio preload | All 13 audio tracks preloaded on module evaluation to avoid latency on first trigger |
| State-gated sounds | Zustand boolean flags prevent duplicate audio on React StrictMode double-renders |
| frameloop: always | Continuous rendering loop for smooth camera interpolation (not demand-based) |
| CameraControls constraints | minDistance/maxDistance/maxPolarAngle prevent degenerate camera states |
GSAP overwrite: auto |
Prevents animation stacking on rapid UI interactions |
Built with passion for precision engineering and the art of driving.
"In the beginning I looked around and, not finding the automobile of my dreams, decided to build it myself." — Ferry Porsche
This is a closed, private project. The source code is not publicly available and is not open for redistribution, forking, or reuse.
All rights reserved © 2025 — This repository is for portfolio and showcase purposes only.
Crafted by R3Vision
R3Vision — A creative development studio focused on pushing the boundaries of real-time 3D, interactive web experiences, and immersive digital products.
From concept to pixel-perfect execution — built with obsession for craft.