WebTide is an ocean simulation based on Jerry Tessendorf's paper, implemented on WebGPU with BabylonJS.
This was my final project for the INF585 "Computer Animation" course at École Polytechnique. The report is online on my blog.
An online demo is available here, and the spherical version is available here.
- GPU-based FFT
- Phillips spectrum
- JONSWAP spectrum
- Wave vertices vertical displacement
- Choppy waves (waves vertices horizontal displacement)
- Physically based ocean shading
- Wrapping on a sphere with triplanar mapping
- Jacobian-based foam
Using the ocean in your own project is straightforward:
// This is the resolution of the wave spectrum. Bigger is better but slower.
const textureSize = 512;
// This is the size of the water plane in meters.
const tileSize = 10;
// Define your base spectrum
const initialSpectrum = new PhillipsSpectrum(textureSize, tileSize, engine);
// Create the water material
const waterMaterial = new WaterMaterial("waterMaterial", initialSpectrum, scene);
// Create a subdivided plane
const water = MeshBuilder.CreateGround(
"water",
{
width: tileSize,
height: tileSize,
subdivisions: textureSize
},
scene
);
// Assign the water material to the plane
water.material = waterMaterial;
// The method to update the material every frame
function updateScene() {
const deltaSeconds = engine.getDeltaTime() / 1000;
waterMaterial.update(deltaSeconds, light.direction);
}
// Register the update method to the scene
scene.executeWhenReady(() => {
scene.registerBeforeRender(() => updateScene());
engine.runRenderLoop(() => scene.render());
});
You can have a look at the code in src/ts/minimal.ts
for the simplest example possible.
You might want to use a custom spectrum for your ocean. No worries, I got you covered.
The WaterMaterial
class takes any object that implements the InitialSpectrum
interface for the initialSpectrum
parameter.
You can copy and paste the code for the Phillips Spectrum (the typescript class and the wgsl shader code) and start from there.
I made this simulation using many different resources found online:
-
Simulating Ocean Water by Jerry Tessendorf
-
GPU-based FFT from BabylonJS Ocean Demo by Popov72
-
Nice specular coefficients from Shadertoy by afl_ext
-
Acerola's excellent video breakdown of Tessendorf's paper
-
Tangent calculations by Rikard Olajos
-
Tropical sunny day skybox from the BabylonJS Asset Library
-
Sand texture from Engin Akyurt
To run the project locally, you need to have Node.js installed. Then, run the following commands:
pnpm install
pnpm run serve
If you don't have pnpm
installed, you can install it with npm install -g pnpm
.