Physically-derived open-ocean swell driven by wind rather than hand-placed sine waves — wind speed, direction, patch length, choppiness and spectrum seed. The most realistic ocean we have shipped.
Oceanology Pro adds a full Tessendorf-style FFT ocean to the wave-source system. A Phillips spectrum is generated once on the CPU, then inverted every frame by a chain of compute shaders into a displacement map and a gradient/foam map that the water material samples directly. It sits alongside the two Gerstner systems as a third selectable wave source, available on every water body actor, and the same spectrum that drives the pixels also drives buoyancy and gameplay water queries.
How the simulation runs
Rendering happens on the render thread inside a render-graph builder. Each frame runs UpdateSpectrumCS, a horizontal inverse FFT, the packed vertical inverse FFT for the horizontal displacement terms, the vertical inverse FFT for the height term, UpdateDisplacementMapCS, GenerateGradientFoldingMapCS, and a copy into the component's render targets. The H0 and Omega structured buffers are persistent and created once; every intermediate FFT resource is transient and tracked by the graph.
The inverse FFT is a Stockham kernel with a per-size configuration selected by shader permutation: 256 uses radix 4 with 64 threads over 4 passes, 512 uses radix 8 with 64 threads over 3 passes, 1024 uses radix 4 with 256 threads over 5 passes, and 2048 uses radix 2 with 1024 threads over 11 passes.
Two outputs are published to the material as DisplacementMap (RGB is XYZ displacement in world units) and GradientFoldingMap (RGB is the unnormalized normal, alpha is foam).
Foam comes from the Jacobian folding term and is advected frame to frame through a ping-pong pair of RGBA32F textures, governed by a decay rate, an additive bias and a gain.
A body set to Baked mode replays a flipbook instead: a compute pass resolves a four-frame Catmull-Rom blend once per texel into the same two compact textures, so baked and runtime paths present identical inputs to the material.
One spectrum, three consumers
The wave source owns the maths and nothing else evaluates it. UOceanologyFFTWavesSource generates H0 and Omega from the spectrum recipe; the FFT component resolves whether that recipe is the runtime one or the baked one, hands it to the source, and then seeds the GPU renderer from the source's own buffers. Render, buoyancy and surface queries therefore cannot drift apart.
CPU height queries evaluate a partial discrete Fourier sum over the 65 by 65 lowest-wavenumber band around the origin, then correct for choppiness by re-sampling at the inverse-displaced position, so a floating object sits on the crest it visually rests on.
Maximum wave height is derived analytically as the significant wave height, four times the square root of twice the summed spectral variance, instead of a guessed multiplier. The water mesh Z bounds and buoyancy both read that value.
An immutable, UObject-free snapshot of the evaluator is published for the Chaos physics thread, so buoyancy can keep querying while the game thread edits or replicates the spectrum.
Dedicated and headless worlds still build the CPU spectrum for buoyancy and water queries, and skip visual FFT initialization and ticking entirely.
Authoring and runtime control
Core spectrum: map resolution, patch length, amplitude scale, wind angle, wind speed, wind dependency, choppy scale and a spectrum seed for reproducible seas.
Advanced: directional exponent, small-wave cutoff, loop period for seamless quantization, time scale and foam delta time.
Foam: decay rate, additive Jacobian bias and gain.
SetEffectiveWaves replicates the whole configuration push-model, so a storm can be pushed from the server to every client.
A Blueprint-pure LerpFFTWaves blends two configurations for weather transitions; resolution and seed take the target value rather than interpolating.
The material-side helper header offers distance-based anti-tiling that blends a jittered second tile between 100 m and 500 m from the camera, plus a three-cascade sampler with distance-derived LOD weights.
Versus Oceanology NextGen
Oceanology NextGen
Oceanology Pro
Deep-water spectrum
Gerstner and Spectral Gerstner only; no FFT code anywhere in the plugin
FFT Waves added as a third selectable wave source alongside both Gerstner systems
Wave evaluation
Analytic sums over a wave component list
GPU inverse FFT over a Phillips spectrum, up to 2048 by 2048
Foam
Threshold on the analytic Jacobian
Jacobian folding advected across frames in a ping-pong RGBA32F pair with decay, bias and gain
Maximum wave height
Derived from the authored wave list
Significant wave height computed from the spectrum's own variance