Skip to main content
← Roadmap
🌊 Oceanology ProIn Progress6.0.0

Breaking waves with a CPU mirror

Waves steepen, curl and break at the shore with foam that follows the coastline — and the CPU sees the same breaking wave the GPU renders, so buoyancy and swimming agree with what you can see.


Shore-breaking waves are their own wave source in Oceanology Pro, independent of whatever deep-water system a body uses. The visual is an offline-authored breaker profile driven by the water zone's JumpFlood shoreline field. The part that matters for gameplay is the CPU mirror: a stateless, thread-safe analytic evaluator that shares the shader's calibration constants verbatim, so buoyancy, swimming and water queries feel the same breaker the camera is looking at.

How the visual profile works

  • Breaking Waves is a separate source whose wave-system selector is None, so it composes with Gerstner, Spectral Gerstner or FFT on the same body rather than replacing them.
  • The shader reads the shoreline from the JumpFlood pass: a signed distance in centimeters, positive in water, and a unit gradient pointing at the nearest shore. A cleared or seedless texel produces nothing at all; the shader never synthesizes a coastline where the data has none.
  • Every offshore point is projected onto the nearest shoreline and one stable world-space component becomes the phase coordinate. That keeps the breaker continuous around islands and curved coasts instead of rotating with the local gradient.
  • The profile itself is a Texture2DArray. Slice 0 stores the forward projection in RG and authored foam in B, slice 1 stores the forward derivatives, slice 2 stores the Eulerian inverse top projection in RG and the lip branch's horizontal projection in B. One- and two-slice profiles remain valid.
  • Value noise on the coast coordinate distorts the lifecycle and the traveling phase, so a line of breakers reads as a coastline rather than a repeating stamp.
  • The shoreline look-ahead used for terrain slope is resolved automatically from the physical breaker scale: two profile footprints or the horizontal displacement reach, clamped between 100 and 4000 cm.

The CPU mirror

FOceanologyBreakingWavePhysicsCPU is a float32 port of the same profile that reproduces the shader's constants one for one, down to the horizontal and vertical calibration factors, the 600 cm reference profile width, the speed and lifecycle calibrations and the three coast-shape frequencies. It compiles with precise floating-point control and contraction disabled so the two implementations cannot quietly diverge.

  • It needs a shoreline of its own. FOceanologyShoreFieldCPU builds one from ground collision heights over the body's XY coverage: sample the ground, derive the wet mask where water sits above ground, dilate it to match the WaterInfo velocity-blur footprint, then run an exact 2D Euclidean distance transform. Conventions match the GPU exactly.
  • Building touches world collision, so it runs on the game thread. Afterwards sampling is const and safe from worker threads, and the field is handed to Chaos as an immutable shared snapshot together with the primary wave evaluator and the numeric breaking recipe.
  • The query path is deliberately tiered. Most samples are deep water or outside coverage and take a depth-only tap; the eight-tap Sobel shore direction is computed only for coastal samples that can actually contribute a breaker. Negative signed distance or non-positive depth returns flat water, which is the guard against waves appearing under terrain.
  • Physics is a selector, not a fixed path. Breaking Wave Profile evaluates the full analytic breaker; Wave Attenuation Water Depth uses the cheaper depth-attenuated primary wave. Disabling the system always resolves to the latter.

What you can build with it

  • Surfable beaches where a boat, a raft or a swimmer is lifted and carried by the same breaker that is rendered.
  • Coastlines with a foam band whose width is a fraction of the physical profile footprint, with a one-texel WaterInfo minimum enforced in the shader so the band stays stable across capture resolutions.
  • Storm and calm transitions, by interpolating the whole configuration with the Blueprint LerpBreakingWaves helper or by swapping a Breaking Waves Preset asset.
  • Server-authoritative gameplay near the shore: the mirror needs no rendering, so a dedicated server evaluates the same surface the clients see.

Versus Oceanology NextGen

Oceanology NextGenOceanology Pro
Profile sourceProcedural breaker profiles generated inside the shaderOffline-authored Texture2DArray with forward, derivative and inverse-top slices; the old experimental visual Physics mode is retired and migrated to the baked path on load
CPU shorelineMirror built on a one-dimensional shoreline approximationExact 2D signed distance field plus a depth grid and capture mask, with depth-only builds when the full transform is not needed
Physics handoffEvaluated through live objectsImmutable, UObject-free snapshot published to the Chaos physics thread
Physics selectionOne pathExplicit Physics Source selector, so a body can keep the full visual breaker while paying only depth attenuation on the CPU
Physics sourceBreaking Wave Profile (default) or Wave Attenuation Water Depth
Profile assetTexture2DArray, up to three slices
Displacement defaultsHorizontal 50, vertical 100, breaker strength 10, break profile control 1.0
CadenceWave frequency in breaker cycles per 600 cm reference profile (default 1.0), direction speed 1.0, negative reverses travel
Foam bandCoast foam width 0.25 of the profile footprint
NoiseScale 256, strength 25 percent, distance 32 percent of one cycle
CPU shore texel size100 cm (r.Oceanology.BreakingWaves.CPUShoreTexelSize)
CPU shore max resolution512 per axis (r.Oceanology.BreakingWaves.CPUShoreMaxResolution)
Rebuild retry30 s after landscape streaming yields no usable shoreline
CPU physics toggler.Oceanology.BreakingWaves.CPUPhysics, default 1, read at startup
Automatic look-aheadClamped 100 to 4000 cm

This is one entry on the Galidar roadmap. For what already shipped in each release, see the Changelog.