WebGPU FFT Ocean Demo
An interactive WebGPU demo that simulates a tiled ocean surface using fast Fourier transforms (FFT).
The project renders a dynamic wave field in real time and exposes a small framework for building WebGPU pipelines, passes and scenes.
Features
- Real‑time ocean surface simulation using 2D FFT.
- Tiled ocean mesh with adjustable resolution and tiling count.
- Multiple shading modes (realistic, lighting, normals, solid color, height debug).
- Wireframe / solid rendering modes.
- Pause / single‑step controls for the simulation.
- CPU vs GPU validation helpers for the FFT and spectrum (accessible from the browser console).
Requirements
- Node.js 18+ (for the simple static file server).
- A browser with WebGPU support:
- Recent Chrome / Edge with WebGPU enabled, or
- Chrome Canary / other WebGPU‑capable build.
Getting Started
-
Install dependencies (only used by some tools):
npm install -
Start the local server:
node server.js -
Open the demo in your browser:
- Navigate to:
http://localhost:3003/index.html
- Navigate to:
If WebGPU is not available, the status label in the bottom‑left of the page will tell you that WebGPU is not supported.
Controls
All controls are in the panel at the top‑right of the page:
- Wave height – overall amplitude of the waves.
- Wave length – scales the wave spectrum (larger values = longer waves).
- Resolution – underlying mesh resolution (32 → 2048).
- Wireframe mode – toggle wireframe rendering.
- Pause waves – pause / resume the simulation.
- Next frame – advance the simulation by one frame while paused.
- Shading – choose between realistic, lighting, normals, solid color, and height debug modes.
- Dump height (debug) – logs statistics about the current height field buffer to the console.
Camera:
- Drag on the canvas to orbit the camera.
- Scroll to zoom in/out.
On first load the camera auto‑rotates until you interact with the canvas.
Debug / Test Helpers
The app exposes a couple of helpers on window for validating the GPU simulation against CPU reference implementations:
-
window.testFft()- Builds a deterministic 2D input field.
- Runs the GPU FFT passes.
- Computes a CPU 2D FFT.
- Logs max and RMS error between GPU and CPU results.
-
window.testSpectrum()- Uses the initial spectrum buffers.
- Runs a CPU reference spectrum computation.
- Runs the GPU spectrum pass.
- Logs max and RMS error between GPU and CPU spectra.
You can call these from the browser devtools console while the app is running.
Project Structure
index.html– minimal HTML shell and UI controls.main.js– application entrypoint; wires up the engine, pipelines, scene, and render loop.events.js– encapsulates DOM element lookup and all UI / input event handlers.server.js– simple Node static file server used during development.
WebGPU framework and rendering:
framework/– generic engine / scene / math utilities and WebGPU plumbing.pipelines/– high‑level render and compute pipelines (e.g.OceanPipeline).passes/– individual compute / render passes used by pipelines.shaders/– WGSL shader programs (FFT, spectrum, rendering, etc.).
Testing / utilities:
tests/OceanTests.js– CPU FFT and spectrum reference implementations wrapped in a small test helper class.resources/,tools/– additional assets and helper scripts.
Notes
- The project is written as native ES modules (
type: "module"inpackage.json). - All WebGPU usage is routed through the small framework in
framework/rather than directGPUDevicecalls scattered throughout the app. - If you change ports or server configuration, update how you access the app accordingly (the default is port
3003).