Case Study 04 · 3D Graphics & Physics Simulations · 2024

Neon Racer 3D — Browser WebGL & Vehicle Dynamics

Rigid-body vehicle dynamics, AWD torque splitting, and 60 FPS Three.js WebGL graphics.

Role & Responsibilities
Graphics & Physics Developer
Primary Stack
Three.js, Cannon-es, WebGL, JavaScript, Vite
Key Engineering Metric
Stable 60 FPS in browser with sub-3MB bundle payload
Status & Verification
Live in Production
60.0 FPS Frame Rate
2.4 MB gzip Payload
40 / 60 AWD Torque Split
Zero Game Engines

Executive Overview

The Problem

3D web games compiled from heavyweight game engines (Unity/Unreal) impose 50–150MB downloads and GC frame drops.

The Architecture

Browser-native Three.js WebGL pipeline combined with Cannon-es raycast suspension, AWD power distribution, and smooth chase camera math.

Engineering Impact

Stable 60 FPS rendering on integrated GPUs, sub-3MB bundle payload, and zero runtime garbage collection pauses.

[ User Input / Gamepad API ] ──► [ Fixed Timestep Physics (Cannon-es @ 60 Hz) ]
                                             │
               ┌─────────────────────────────┴─────────────────────────────┐
               ▼                                                           ▼
     [ Raycast Suspension Math ]                                 [ AWD Torque & Slip Model ]
     - 4 Downward Raycasts                                       - 40% Front / 60% Rear Bias
     - Hooke's Law Spring & Damper                               - Speed-Damped Steering
               │                                                           │
               └─────────────────────────────┬─────────────────────────────┘
                                             ▼
                        [ Transform State Interpolator ]
                                             │
                                             ▼
                        [ Three.js WebGL Render Pipeline ]
                        - Dual-Spring Look-Ahead Camera
                        - Instanced Particle Systems & Shaders

Technical Architecture

1. Raycast Suspension & Vehicle Dynamics

Casts 4 vertical rays from chassis corners to compute surface contact and apply suspension forces:

\[F_{\text{suspension}} = k \cdot (L_0 - L) - c \cdot v_{\text{suspension}}\]
Raycast Suspension Controller JavaScript
```javascript class VehiclePhysicsController { constructor(world, chassisBody) { this.vehicle = new CANNON.RaycastVehicle({ chassisBody: chassisBody, indexRightAxis: 0, indexUpAxis: 1, indexForwardAxis: 2 }); const opts = { radius: 0.35, directionLocal: new CANNON.Vec3(0, -1, 0), suspensionStiffness: 45, suspensionRestLength: 0.4, frictionSlip: 2.8 }; const hw = 0.85, hl = 1.35, y = -0.1; this.vehicle.addWheel({ ...opts, chassisConnectionPointLocal: new CANNON.Vec3(-hw, y, hl) }); // FL this.vehicle.addWheel({ ...opts, chassisConnectionPointLocal: new CANNON.Vec3(hw, y, hl) }); // FR this.vehicle.addWheel({ ...opts, chassisConnectionPointLocal: new CANNON.Vec3(-hw, y, -hl) }); // BL this.vehicle.addWheel({ ...opts, chassisConnectionPointLocal: new CANNON.Vec3(hw, y, -hl) }); // BR this.vehicle.addToWorld(world); } } ```

2. AWD Torque Splitting & Look-Ahead Camera

Splits drive torque 40/60 and tracks chassis motion using exponential look-ahead interpolation:

AWD Power & Camera Interpolation JavaScript
```javascript updateVehicleInputs(inputs, deltaTime) { const maxForce = 1800; this.vehicle.applyEngineForce(inputs.throttle * maxForce * 0.4, 0); // FL this.vehicle.applyEngineForce(inputs.throttle * maxForce * 0.4, 1); // FR this.vehicle.applyEngineForce(inputs.throttle * maxForce * 0.6, 2); // BL this.vehicle.applyEngineForce(inputs.throttle * maxForce * 0.6, 3); // BR const speed = this.vehicle.chassisBody.velocity.length(); const steer = inputs.steer * 0.48 * Math.max(0.45, 1.0 - (speed / 45.0)); this.vehicle.setSteeringValue(steer, 0); this.vehicle.setSteeringValue(steer, 1); } ```

Key Takeaways & Verification

  • Frame Rate & Memory: Continuous 60.0 FPS with zero runtime garbage collection pauses via pre-allocated vector scratchpads.
  • Payload Efficiency: Entire application (Vite + Three.js + Cannon-es + shaders + SFX) ships at 2.4 MB gzip.