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.jsbootstraps the WebGPU context, loads WGSL compute shaders, and drives the render loop.js/wgsl/*.jsfiles export WGSL modules for ocean simulation (sim.js), wave shading (ocean.js), sky rendering (sky.js), and post‑processing (post.js).index.htmland the minifiedocean.min.htmlhold the UI, camera controls, and a single<canvas>element; they loadmain.jsthrough<script type="module">.
How It Is Wired
Entry point: index.html → loads js/main.js as a module.
main.jscallsinitWebGPU()(insidemain.js) to request an adapter and device.initWebGPU()creates aGPUCanvasContextand builds a pipeline by importing WGSL modules from thejs/wgsl/folder.- The main render loop (
render()) invokes: -simulateOcean()– dispatches the compute shader fromsim.jsto populate texture buffers. -drawOcean()– uses the vertex shader fromocean.jsto render the CDLOD quadtree mesh, sampling the displacement from the simulation textures. -drawSky()– runs the sky pipeline fromsky.jsto build an environment cube map each frame. -postProcess()– applies bloom and tone mapping via the shader inpost.js. - User input is handled by event listeners attached to the canvas; camera state is updated in
main.jsand 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.