๐ Three Wave Systems - FFT, Gerstner & Spectral in Oceanology Pro 2.0
Oceanology Pro 2.0 ships with three complete wave systems โ FFT, Gerstner, and Spectral Gerstner โ all usable in the same project. Each wave body can independently select its wave system via the WaveSystemSelector, so you can combine cinematic FFT oceans with performant Gerstner lakes in a single level.
๐๏ธ Wave System Overviewโ
| System | Best For | GPU Cost | Realism | Control |
|---|---|---|---|---|
| FFT | Cinematic oceans, film-quality water | High (RTX 3080+) | โญโญโญโญโญ | Physics-based |
| Gerstner | Games, wide hardware support | Low (GTX 1080+) | โญโญโญ | Fully manual |
| Spectral Gerstner | Balanced quality/performance | Medium | โญโญโญโญ | Beaufort-driven |
All three systems output the same interface (Displacement, Normal, Foam), so downstream features โ buoyancy, breaking waves, foam, caustics โ work identically regardless of which wave system you choose.
๐ FFT Waves (Fast Fourier Transform)โ
The most physically accurate option. FFT simulates the full ocean spectrum using GPU compute shaders.
How It Worksโ
- Spectrum Generation โ A Phillips or JONSWAP energy spectrum is generated based on wind parameters
- Inverse FFT โ GPU compute shaders transform the frequency-domain spectrum to spatial-domain displacement via horizontal and vertical IFFT passes
- Gradient Folding โ A second pass computes normals and Jacobian-based foam from the displacement map
Key Featuresโ
- GPU Compute Pipeline โ Dedicated compute shaders for spectrum update, IFFT, and gradient computation
- Displacement + Gradient Render Targets โ XYZ displacement and folding maps updated every frame
- Wave Baking โ Bake FFT output into flipbook atlases for zero-cost playback in shipped games
- Configurable Resolution โ From 64ร64 (fast) to 512ร512 (cinematic)
When to Use FFTโ
- Film/cinematic sequences where quality is paramount
- ArchViz projects requiring photorealistic water
- High-end PC/console games with RTX 3080+ minimum spec
- Any project that needs wave baking for performance
โ๏ธ Gerstner Waves (Legacy)โ
The proven, performance-first approach. Manually stack 4-8 analytical Gerstner waves with full parameter control.
How It Worksโ
Each wave is defined by amplitude, wavelength, direction, and steepness. The CPU-friendly analytical formula produces displacement and normals without GPU compute.
Key Featuresโ
- Manual Control โ Tune each individual wave for exact artistic direction
- Lowest GPU Cost โ Runs efficiently on GTX 1080 and up
- Preset System โ One-click ocean configurations for common scenarios
- Wave Baking โ Bake Gerstner output into flipbook atlases too
When to Use Gerstnerโ
- Mobile or low-spec hardware targets
- Stylized water that needs precise artistic control
- Projects where every millisecond of GPU budget matters
- Simple lake or pool simulations
๐ฌ Spectral Gerstner Wavesโ
Real ocean surfaces are the result of wind energy distributed across a spectrum of frequencies. Our Spectral Gerstner system simulates this by:
- Generating many wave components (up to 128) across the frequency spectrum
- Distributing energy according to oceanographic models
- Aligning waves around the wind direction with natural spreading
- Using proper dispersion for physically correct wave speeds
The Beaufort Scaleโ
Instead of abstract parameters, you now control the ocean using the Beaufort Wind Force Scale (0-12):
| Beaufort | Description | Wave Height | Sea State |
|---|---|---|---|
| 0 | Calm | 0 m | Mirror-like |
| 3 | Gentle Breeze | 0.6 m | Large wavelets |
| 5 | Fresh Breeze | 2.0 m | Moderate waves |
| 7 | Near Gale | 4.0 m | Sea heaps up |
| 9 | Strong Gale | 7.0 m | High waves |
| 12 | Hurricane | 14+ m | Air filled with foam |
Simply set BeaufortScale = 5 and the entire wave spectrum adjusts accordingly!
๐ Technical Implementationโ
Deep Water Dispersionโ
Our waves follow the deep water dispersion relation:
ฯ = โ(g ร k)
Where:
- ฯ = angular frequency (wave speed)
- g = gravity (981 cm/sยฒ)
- k = wave number (2ฯ/ฮป)
This ensures longer waves travel faster than shorter waves - exactly like real oceans.
Energy Distributionโ
Wave amplitudes follow an exponential energy distribution:
const float energy = pow(waveT, WaveEnergyDistribution);
float lambda = lerp(adjMaxL, adjMinL, energy);
const float A = lerp(adjMaxH, adjMinH, energy);
This creates the characteristic ocean spectrum with dominant swells and diminishing high-frequency components.
Directional Spreadingโ
Waves spread naturally around the wind direction:
const float spreadAngle = DirectionalVariance * HALF_PI;
const float angOff = sign(rand.x - 0.5) * pow(rand.y, 0.8) * spreadAngle;
Set DirectionalVariance = 30 for realistic spreading, or increase for more chaotic seas.
Detail Bandโ
To capture high-frequency ripples without excessive wave count, we add a detail band at 5x the base frequency:
#define DETAIL_FACTOR 5.0f // frequency multiplier
#define AMPLITUDE_SCALE 0.1f // relative amplitude
This adds realistic surface texture without additional computational cost.
โ๏ธ Parameters Referenceโ
USTRUCT(BlueprintType)
struct FOceanologySpectralGerstner
{
// Master enable
bool SpectralGerstnerWaves = true;
// Wind conditions
float BeaufortScale = 5.0; // 0-12 wind force
float DirectionalVariance = 30.0; // 3-90 degrees
FVector2D WindDirection = (1, 1); // Normalized direction
// Wave spectrum
float WaveComponentCount = 128.0; // 4-128 waves
float WaveSpectrumResolution = 1.0; // 0.5-1.0 quality
float WaveEnergyDistribution = 1.0; // Energy falloff
// Wave bounds
float MaxWaveHeight = 13.7; // Tallest swell (cm)
float MinWaveHeight = 0.25; // Smallest ripple (cm)
float MaxWaveLength = 13312.0; // Longest wave (cm)
float MinWaveLength = 128.0; // Shortest wave (cm)
// Foam generation
float FoamThresholdLow = -0.2; // Calm foam bias
float FoamThresholdHigh = -0.525; // Storm foam bias
float SmallWaveThreshold = 0.25; // Capillary cutoff
};
๐จ Artistic Controlโ
While physically-based, the system offers full artistic control:
For Realistic Oceansโ
BeaufortScale: 4-6
DirectionalVariance: 25-35
WaveComponentCount: 64-128
For Stylized Waterโ
BeaufortScale: 2-3
DirectionalVariance: 10-20
WaveComponentCount: 16-32
WaveEnergyDistribution: 2.0 (more uniform)
For Stormy Seasโ
BeaufortScale: 8-10
DirectionalVariance: 45-60
FoamThresholdHigh: -0.7
๐ Performance Considerationsโ
The spectral system is highly optimized:
- Loop unrolling where beneficial
- SIMD-friendly operations (sincos pairs)
- RCP intrinsics for divisions
- Early Beaufort scaling to reduce per-wave work
Benchmark (RTX 4070, 1080p):
- 32 waves: ~0.3ms
- 64 waves: ~0.5ms
- 128 waves: ~0.9ms
For most projects, 64 waves provides excellent quality with minimal overhead.
๐ Combining with Breaking Wavesโ
Spectral waves blend seamlessly with the new Breaking Wave system:
// Ocean provides base motion
OutDisplacement = SpectralWaves.WPO;
OutNormal = SpectralWaves.Normal;
// Breaking waves override near shore
OutNormal = lerp(BreakingNormal, OceanNormal, OceanBlend);
OutFoam = lerp(ShoreFoam, OceanFoam, OceanBlend);
The OceanBlend factor ensures smooth transitions from deep water to surf zone.
๐ Choosing Your Wave Systemโ
| Scenario | Recommended System |
|---|---|
| Open ocean, cinematic | FFT |
| Open ocean, game-optimized | Spectral Gerstner |
| Lake, pool, stylized | Gerstner |
| Mixed project | FFT for hero ocean + Gerstner for background lakes |
Quick Setupโ
- Select your water body in the editor
- Set
WaveSystemSelectorto your chosen system - Configure system-specific parameters:
- FFT: Resolution, wind speed, spectrum type
- Gerstner: Individual wave amplitude, wavelength, direction
- Spectral:
BeaufortScale,WindDirection,DirectionalVariance
All three systems support Wave Baking for shipped games โ bake once, play back with near-zero GPU cost.
๐ Further Readingโ
- Original Gerstner Paper (1804)
- Tessendorf's "Simulating Ocean Water" (FFT reference)
- Beaufort Scale (Wikipedia)
- Technical Architecture โ Wave System Selector
Questions about wave systems? Join our Discord and ask!