The Problem

Clients need a ready‑to‑run, zero‑dependency ocean simulation that can be embedded in a browser without a heavy engine. Existing demos often bundle large libraries or require a build step that obscures the core WebGPU logic. This repo offers a single‑page, self‑contained renderer that exposes wave, sky, and camera controls through simple URL parameters.

What This Does

The project implements a Tessendorf FFT ocean, physically‑based sky, and post‑processing in pure WebGPU.

  • js/main.js bootstraps the WebGPU context, loads WGSL compute shaders, and drives the render loop.
  • js/wgsl/*.js files export WGSL modules for ocean simulation (sim.js), wave shading (ocean.js), sky rendering (sky.js), and post‑processing (post.js).
  • index.html and the minified ocean.min.html hold the UI, camera controls, and a single <canvas> element; they load main.js through <script type="module">.

How It Is Wired

Entry point: index.html → loads js/main.js as a module.

  1. main.js calls initWebGPU() (inside main.js) to request an adapter and device.
  2. initWebGPU() creates a GPUCanvasContext and builds a pipeline by importing WGSL modules from the js/wgsl/ folder.
  3. The main render loop (render()) invokes: - simulateOcean() – dispatches the compute shader from sim.js to populate texture buffers. - drawOcean() – uses the vertex shader from ocean.js to render the CDLOD quadtree mesh, sampling the displacement from the simulation textures. - drawSky() – runs the sky pipeline from sky.js to build an environment cube map each frame. - postProcess() – applies bloom and tone mapping via the shader in post.js.
  4. User input is handled by event listeners attached to the canvas; camera state is updated in main.js and passed to the vertex shaders each frame.

The flow touches only the browser’s GPU device and the DOM; no external network or filesystem calls occur during runtime. The module graph is a shallow tree: main.js → WGSL modules → render loop. There are no circular dependencies; the only hub is main.js, which coordinates all subsystems.

How To Use It

Setup

git clone https://github.com/moses-y/web-ocean
cd web-ocean
npm install

Build (produces build.mjs and minified HTML)

npm run build

Run locally – the dev server serves index.html on http://localhost:8080/.

npm start

Alternatively, open ocean.html or ocean.min.html directly via file://; both are fully self‑contained.

Configuration – all tunables are URL query parameters (windSpeed, swellHs, sunElev, etc.) or UI controls. No external config files are required.

Real‑World Use

A web‑based visualization portal can embed ocean.min.html in an iframe to provide an interactive ocean demo. Because the renderer is a single file, it can be served as a static asset from a CDN, reducing load times for mobile users. Example:

<iframe src="/ocean.min.html?windSpeed=12&swellHs=2" width="800" height="600"></iframe>

Code Health & Issues

  • Medium (SDLC) – No test files; repository has no CI/CD configuration.
  • Low – No license file; the project uses the default MIT license but it is not present.
  • Low – docs/ contains only images; no README or code comments explain WGSL modules.

These observations come from static inspection of the repository tree.

The Bottom Line

For a developer needing a compact, browser‑only ocean simulation, this repo delivers a high‑quality WebGPU renderer with minimal setup. The lack of tests and CI is a drawback for production use, but the codebase is small and straightforward enough that adding unit tests or a GitHub Actions workflow would be inexpensive. Use it as a reference implementation or embed it in a lightweight web demo.