Humpalumps/Ultra-Water

★ 213⑂ 33

Real-time FFT ocean renderer for three.js (WebGL2): shore breakers, foam, caustics, underwater rendering and buoyancy at 200+ fps

About Humpalumps/Ultra-Water

Humpalumps/Ultra-Water is an open-source project on GitHub, mainly written in JavaScript. Real-time FFT ocean renderer for three.js (WebGL2): shore breakers, foam, caustics, underwater rendering and buoyancy at 200+ fps It currently holds 213 stars and 33 forks with 0 open issues, and was last pushed on 2026-10-28 (repository created 2026-10-28).

Project Overview

Git Homed tracks it on the Today's Trending board, currently at rank #32 with 0 new stars today.

GitHub Repository Details

Repository Humpalumps/Ultra-Water · default branch master · size 136 KB · watchers 4 · source: GitHub REST API and repository README

README

Ultra Water

Real-time ocean renderer for three.js (WebGL2), with a demo island scene.

npm install
npm run dev

Open the printed localhost URL. Orbit with the mouse (or a finger: phones get their own profile, see Phones and tablets). Pick shots from the camera dropdown (they also set the sun). The performance panel (top left) shows the GPU, render size, fps, ms per frame and a 20 s graph. Its Uncap FPS button switches the loop off the display's refresh: frames then render back-to-back, with at most three in flight on the GPU, so the counter shows what the machine can do while the scene keeps running live. The screen still updates at its own rate. Cap to display switches back. Run benchmark (also benchmark (uncapped) in the settings) renders 300 frames back-to-back with the render loop paused and times them to GPU completion with a fence. The screen freezes for about a second while it runs, so it only runs when asked.

Performance

Measured with the in-page benchmark on an RTX 3060 (Chrome, ANGLE/D3D11), 4× MSAA, all features on, at 1954×1692 (3.3 MP, the pixel count of 1440p; devicePixelRatio 2 on the browser window):

| Shot | ms / frame | fps (uncapped) | |---|---|---| | Open ocean | 3.30 | ~303 | | Breakers | 4.17 | ~240 | | Golden hour | 4.20 | ~238 | | Lagoon | 4.48 | ~223 | | Flotsam (10 floating props) | 4.62 | ~217 | | Underwater | 4.71 | ~212 | | Aerial | 4.80 | ~208 |

Per pass in Breakers: water 1.66 ms, opaque (island, rocks, props) 1.21, post 0.37, caustics 0.24, FFT sim ~0.45 (independent of resolution). Caustics cost more under a low sun (about 0.36 ms at 3.5° elevation), because the refracted rays fold more.

The crest-foam upgrade landed after this run. It adds three texture taps and some ALU per foam pixel only. It hasn't been re-measured cleanly yet, because another application was loading the GPU at the time.

Earlier versions of this README quoted numbers 2–4× lower. Those came from a benchmark that synced with readPixels/finish, which ANGLE doesn't wait on. The fence-based benchmark is the one to trust. The HUD's GPU timer-query numbers read high while vsync-capped, because the GPU downclocks between frames.

Phones and tablets

The same build spots phones and tablets (a finger as the main pointer, matchMedia('(pointer: coarse)')) and starts them on a lighter profile. Desktop is unchanged. Add ?mobile or ?desktop to the URL to force either.

The mobile profile is resolution 0.6 (of the device pixel ratio, capped at 2), 2× MSAA, reflections at 0.35 scale and no bloom. On a phone the cost is mostly the number of render passes Chrome's GPU process has to translate, not pixels, so dropping bloom's 12 passes did more than lowering resolution. Auto resolution (auto resolution in the Quality folder) steps down by 0.05, to a floor of 0.5, when more than 4% of frames miss vsync over 2 s. It climbs back to 0.6 once frames are clean, and locks to a steady 30 fps if the floor still misses more than a quarter.

Measured on a OnePlus Nord 4 (Snapdragon 7+ Gen 3, Adreno 732, Chrome 156, which runs pages at 60 Hz on it), portrait, 424×782:

| Shot | live fps | missed frames | fps (uncapped) | |---|---|---|---| | Open ocean | 60 | 0% | 142 | | Aerial | 60 | 0% | 118 | | Underwater | 60 | 0% | 103 | | Lagoon | 60 | 0% | 102 | | Flotsam | 60 | 0% | 101 | | Golden hour | 60 | 0% | 99 | | Breakers | 60 | 0% | 95 |

With the desktop settings (708×1304, 4× MSAA, bloom) the same phone ran 41–50 fps live, missing up to a third of its frames, and 62 fps uncapped on average. Phone numbers move with temperature. These were taken warm (thermal status 1) while charging over USB.

What's in it

Waves (src/water/OceanSim.js)

Surface (src/water/OceanSurface.js) Caustics (src/water/Caustics.js) Underwater (src/water/UnderwaterPass.js, underside branch in OceanSurface.js) Floating objects (src/water/WaterQuery.js, src/scene/floaters.js, src/scene/floaterMeshes.js, src/scene/floaterShadow.js) Pipeline (src/main.js) 1. Ingest the last water query, step the floaters, then: 2. Planar reflection (half res, skipped underwater). 3. Opaque pass into a single 4× MSAA HDR target. 4. Water pass, depth-tested against the kept MSAA depth for correct per-sample edges. 5. Underwater pass, when near or below the surface. 6. Post (PostFX.js): Scene The Water folder has a colour preset dropdown (clear, tropical, toxic green, purple, rust orange, murky brown). Each sets the absorption, in-scatter colour, thin-foam tint and underwater scattering together; clarity and scatter still adjust on top.

Camera presets Flotsam and Underwater spawn a field of floating props. The Floaters & underwater folder has spawn, drop and clear buttons, plus drag, buoyancy, scattering, shaft and meniscus controls.

Not in yet

The design was argued out with a second agent before building, and again for each round of upgrades.

License

MIT, see LICENSE. Code adapted from other projects is listed in THIRD_PARTY_NOTICES.md.

GitHub Stars & Activity

213Stars
33Forks
0Open issues
JavaScriptLanguage

GitHub Popularity

GitHub stars213
Forks33
Open issues0
Primary languageJavaScript
LicenseMIT
Stars gained today0
Created2026-10-28
Last pushed2026-10-28

Trending History

Daily boardrank #32 · ▲ 0 stars

Related GitHub Projects

1

jacke-pp / open-yoki

JavaScript★ 340⑂ 1
→
2

haydenschmitty / floorplan

JavaScript★ 322⑂ 31
→
3

HRuiCcc / RuiC-PoseAtlas

JavaScript★ 243⑂ 72
→
4

Mieksido / surfcore

JavaScript★ 206⑂ 15
→
5

davemessew / AgentFlux

JavaScript★ 205⑂ 0
→
6

SAOS-3624 / dsh-video-storyboard

JavaScript★ 147⑂ 13
→
7
→
8
→

More Trending Repositories