Real-Time Ocean Wave Simulation with Compute Shaders

Modern video games achieve lifelike ocean surfaces by offloading complex fluid mathematics to GPU compute pipelines. By utilizing compute shaders to execute algorithms like the Fast Fourier Transform (FFT) and Gerstner wave equations across thousands of parallel threads, developers can dynamically calculate surface displacement, surface normals, foam distribution, and buoyancy physics entirely in real time without bottlenecking the CPU.

The Mathematical Foundation: Statistical Wave Models

Realistic deep-ocean simulation relies on statistical models based on oceanographic research, most notably the Tessendorf wave model. Instead of simulating individual water molecules, developers generate ocean surfaces in the frequency domain using empirical wave spectra, such as the Phillips or JONSWAP spectrum.

These spectra model how wind speed, fetch, and direction generate wave energy across various frequencies. To convert these frequency-domain wave states into actual physical spatial displacements (height, X, and Z offsets), developers use the Inverse Fast Fourier Transform (IFFT). Compute shaders are ideally suited for IFFT calculations because the transform can be broken down into a series of parallel 1D butterfly passes across rows and columns of a 2D texture.

The Compute Shader Pipeline

The ocean simulation lifecycle on the GPU typically executes in a multi-stage compute pipeline every frame:

  1. Spectrum Generation: A compute shader calculates initial wave states based on current wind parameters and time variables, storing complex amplitudes in GPU texture buffers.
  2. Time Evolution and Conjugation: Another compute pass updates the wave phases over time to animate the motion.
  3. IFFT Execution: The pipeline executes horizontal and vertical IFFT compute passes. Modern implementations use shared memory within thread groups (wavefronts/warps) to maximize memory bandwidth during the matrix transpositions and calculations.
  4. Map Generation: The output is resolved into displacement maps, normal maps (for surface lighting), and auxiliary diagnostic maps.

The resulting displacement maps are then fed into the vertex shader stage of the ocean mesh, deforming the flat geometry into turbulent, peaked waves.

Cascaded Grids and Level of Detail (LOD)

Ocean surfaces require fine detail near the camera and massive, broad swells extending to the horizon. Simulating a single massive grid with enough resolution to capture both extremes is computationally inefficient.

Developers solve this using cascaded displacement grids. The compute pipeline generates multiple FFT simulations simultaneously at different spatial scales:

  • High-frequency cascade: Covers a small area around the player to simulate small ripples and capillary waves.
  • Mid-frequency cascade: Covers an intermediate zone for standard chop and waves.
  • Low-frequency cascade: Covers hundreds of square kilometers to model large ocean swells.

In the vertex and pixel shaders, these cascades are blended together using distance-based Level of Detail (LOD) systems, such as screen-space projected grids or quadtrees (CDLOD).

Dynamic Foam and Jacobian Peak Detection

Photorealistic water requires dynamic foam that naturally accumulates at wave crests and turbulent areas. Compute pipelines calculate the Jacobian determinant from the horizontal and vertical displacement vectors.

When water compresses horizontally at the peak of a wave, the Jacobian determinant drops below a critical threshold, indicating wave pinching and overturning. The compute shader uses this condition to inject foam into a persistent, decaying foam buffer. This buffer accounts for dissipation rates, shoreline collision, and wind spray over time.

CPU-GPU Physics Synchronization

Gameplay mechanics such as floating debris, swimming characters, and navigating ships require real-time knowledge of wave heights. Evaluating wave heights on the CPU can cause synchronization overhead or calculation mismatches with the GPU.

Modern engines handle buoyancy in two ways:

  • Asynchronous GPU Readback: The compute pipeline samples wave heights at specific entity coordinates and transfers the data back to the CPU with a few frames of latency, using predictive smoothing to eliminate visual stutter.
  • Shared Mathematical Kernels: For zero-latency physics, a simplified analytic version of the wave generator (often Gerstner-based) is evaluated directly on the CPU or within a dedicated physics compute pass that directly updates rigid body velocities.