A GPU-accelerated wave animation generator using Fourier synthesis, perfect for creating seamlessly tileable animated normal maps and height maps for games and visual effects.
- Mathematical wave generation using sum of sinusoids
- Natural, ocean-like wave patterns with up to 8 configurable components
- Real-time GPU rendering with WebGL 2.0/1.0
- Wave sharpening for realistic oscilloscope-like waveforms
- Temporal frequencies constrained to integers for mathematically guaranteed loop continuity
- Customizable loop duration and playback speed
- Seamless temporal loops perfect for game engines
- Spatial frequencies quantized for seamless texture tiling
- Perfect for game engine texture mapping
- No visible seams when tiled in any direction
- Each wave layer can be distorted by static, tileable Perlin noise
- Noise is perfectly seamless and does not animate (static pattern)
- Noise parameters (amount, scale, seed) are configurable per layer
- Noise scale is integer and required for perfect tiling
- Noise seed allows for unique patterns per layer
- Normal Maps: RGB normal maps for surface detail and lighting effects
- Height Maps: Grayscale displacement maps for tessellation and vertex displacement
- Export animation sequences as ZIP files
- Configurable resolution (256x256 to 4096x4096)
- Configurable frame count (1-600 frames)
- Organized file naming with mode prefixes (now includes date and time)
- Export current settings as JSON presets (now includes date and time in filename)
- Import and share preset configurations
- All per-layer lock states are saved and restored
- Version-controlled preset format with backward compatibility
- Live parameter adjustment with instant visual feedback
- Randomization tools for quick exploration (noise scale always integer)
- Auto-save functionality for persistent settings
- Lock/unlock any parameter per layer, including noise parameters
- Modern web browser with WebGL support
- Local HTTP server (for file access)
-
Clone the repository
git clone https://github.com/yourusername/fourier-wave-generator.git cd fourier-wave-generator -
Start a local server
# Using Python 3 python -m http.server 8000 # Using Python 2 python -m SimpleHTTPServer 8000 # Using Node.js npx http-server -p 8000 # Using PHP php -S localhost:8000
-
Open in browser
http://localhost:8000 -
Start creating waves! 🌊
- Configure Wave Layers: Adjust amplitude, frequency, direction, phase, and noise for each Fourier component
- Set Global Parameters: Configure wave scale, normal intensity, and height range
- Choose Output Mode: Select between normal maps or height maps
- Export Animation: Generate ZIP file with your animation sequence
Each Fourier component includes:
| Parameter | Range | Description |
|---|---|---|
| Amplitude | 0.01 - 1.0 | Wave height and intensity |
| Spatial Frequency | 0.1 - 5.0 | Wave density in space |
| Temporal Frequency | 1-16 | Animation speed for perfect looping |
| Direction X/Y | -1.0 - 1.0 | Wave propagation direction |
| Phase | 0 - 2π | Initial phase offset |
| Sharpness | 0.0 - 1.0 | Wave shape sharpening |
| Noise Amount | 0.0 - 2.0 | Strength of noise distortion |
| Noise Scale | 1 - 8 | Size/period of the noise |
| Noise Seed | 0.0 - 100.0 | Unique randomization for noise pattern |
- Any parameter (including noise) can be locked per layer to prevent randomization or preset overwrite.
- Lock states are saved and restored with presets.
- Static, tileable Perlin noise is applied to each wave layer's phase, distorting the wave lines.
- Noise is perfectly seamless in both space and (if animated) time, but is currently static (does not animate).
- Noise scale must be integer for perfect tiling.
- Each layer can have a unique noise pattern via the seed parameter.
- Noise controls are available in the UI for each layer.
- Purpose: Surface detail and lighting effects
- Format: RGB normal maps
- Controls: Normal intensity, normalize normals
- Use Cases: Game lighting, material effects
- Purpose: Displacement and tessellation
- Format: Grayscale displacement maps
- Controls: Height range, normalize heights
- Use Cases: Vertex displacement, terrain generation
This wave generator implements a sophisticated multi-layer Fourier synthesis system that creates realistic ocean wave patterns through mathematical modeling of wave physics. The system goes beyond simple sine wave summation by incorporating wave sharpening, analytical derivatives, and seamless tiling mathematics.
The fundamental approach uses Fourier analysis to decompose complex wave patterns into simpler sinusoidal components:
H(x,y,t) = Σᵢ Aᵢ × f(sin(φᵢ), sᵢ)
Where each wave component i has:
- Amplitude (
Aᵢ): Controls wave height - Spatial Frequency (
fᵢ): Controls wave density/spacing - Temporal Frequency (
ωᵢ): Controls wave speed - Direction (
d⃗ᵢ): Controls wave propagation direction - Phase Offset (
φ₀ᵢ): Controls wave positioning - Sharpness (
sᵢ): Controls wave profile shape
The phase determines the wave's position in space and time:
φᵢ = k⃗ᵢ · uv⃗ + ωᵢt + φ₀ᵢ
Components:
k⃗ᵢ = (kₓ, kᵧ): Wave vector determining spatial frequency and directionuv⃗: Texture coordinates (spatial position)ωᵢt: Temporal component for animationφ₀ᵢ: Phase offset for wave positioning
The key innovation is the wave sharpening function that transforms smooth sine waves into realistic, sharp-crested wave profiles:
sharpenWave(wave, sharpness) = mix(wave, transformed_wave, sharpness)
Transformation Process:
- Power Parameter:
p = 1/(1 + sharpness × 4) - Valley Targeting:
y₀ = -wave - Negative Space Shift:
y₁ = y₀ - 1 - Power Function:
y₂ = -(-y₁)^(1/p) - Recentering:
y₃ = y₂ + 1 - Normalization:
y₄ = 2(y₃ - min)/(max - min) - 1 - Orientation Restore:
y₅ = -y₄
This creates oscilloscope-like waveforms with:
- Sharp, deep valleys (wave troughs)
- Flattened, shaped peaks (wave crests)
- Realistic wave asymmetry
For seamless texture tiling, wave vectors are quantized to ensure integer wave cycles:
kₓ = round(fᵢ × dₓ) × 2π
kᵧ = round(fᵢ × dᵧ) × 2π
This guarantees that waves complete exact integer cycles across the [0,1] texture space, eliminating seams when tiling.
Note: Perlin noise distortion is also quantized and periodized for perfect tiling, using integer noise scale and periodic boundary conditions.
Normal vectors are calculated using analytical derivatives rather than finite differences for maximum precision:
∂H/∂x = Σᵢ Aᵢ × sharpenDerivative(cos(φᵢ), sᵢ) × kₓᵢ
∂H/∂y = Σᵢ Aᵢ × sharpenDerivative(cos(φᵢ), sᵢ) × kᵧᵢ
The surface normal is computed from the gradient:
n⃗ = normalize((-∂H/∂x × intensity, -∂H/∂y × intensity, 1))
Output in normal map format: n⃗ × 0.5 + 0.5 (maps [-1,1] to [0,1])
Optional normalization ensures full dynamic range usage:
H_normalized = 2 × (H - H_min)/(H_max - H_min) - 1
Where theoretical bounds are:
H_min = -Σᵢ |Aᵢ|(all waves in destructive interference)H_max = +Σᵢ |Aᵢ|(all waves in constructive interference)
Smooth looping animation is achieved through:
t_normalized = (t mod loop_duration) / loop_duration
With integer temporal frequencies ensuring perfect loops.
Optional gradient normalization for consistent normal intensity:
gradient_normalized = (gradient / |gradient|) × scale
The mathematical model approximates real ocean wave behavior:
- Dispersion: Different frequency components travel at different speeds
- Superposition: Multiple wave trains combine linearly
- Directional Spreading: Waves propagate in various directions
- Nonlinear Effects: Wave sharpening simulates wave steepening and breaking
- Statistical Properties: Fourier synthesis matches observed ocean spectra
- Careful handling of division by zero in normalization
- Clamping of output values to valid ranges
- Robust handling of edge cases in power functions
- Analytical derivatives eliminate sampling overhead
- Efficient loop unrolling for fixed layer counts
- Optimized trigonometric function usage
- High-precision floating point for temporal consistency
- Careful phase accumulation to prevent drift
- Quantization strategies for seamless tiling
This mathematical foundation enables the generation of highly realistic, animatable wave patterns suitable for real-time rendering applications while maintaining computational efficiency and visual quality.
// Preset format example
{
"version": "1.0",
"name": "Ocean Waves",
"settings": {
"loopDuration": 2.0,
"speed": 1.0,
"layerCount": 4,
"outputMode": "normal",
"waveScale": 1.0,
"normalIntensity": 1.0,
"heightRange": 1.0,
"waveLayers": [
{
"amplitude": 0.8,
"spatialFreq": 0.5,
"temporalFreq": 1,
"direction": { "x": 1.0, "y": 0.0 },
"phase": 0.0,
"sharpness": 0.2,
"noiseAmount": 0.5,
"noiseScale": 4,
"noiseSeed": 12.3,
"locked": {
"amplitude": false,
"spatialFreq": false,
"temporalFreq": false,
"direction": false,
"phase": false,
"sharpness": false,
"noiseAmount": false,
"noiseScale": false,
"noiseSeed": false
}
}
]
}
}- Click "📁 Import Preset"
- Select your JSON preset file
- Settings will be automatically applied
- Preset is saved to local storage
- All lock states and noise parameters are restored.
- Ocean Surfaces: Realistic water for open-world games
- Lake Effects: Calm water with gentle ripples
- River Systems: Flowing water with directional waves
- Procedural Textures: Generate unique wave patterns
- Material Design: Create custom water materials
- WebGL 2.0: Primary rendering with fallback to WebGL 1.0
- Fragment Shaders: GPU-accelerated wave computation
- Real-time Updates: 60 FPS animation with live parameter changes
- Fourier Synthesis: Sum of sinusoidal wave components
- Seamless Tiling: Quantized spatial frequencies
- Perfect Looping: Integer temporal frequencies
- Wave Sharpening: Mathematical transformation for realistic shapes
| Browser | Version | WebGL Support |
|---|---|---|
| Chrome | 51+ | ✅ Full |
| Firefox | 51+ | ✅ Full |
| Safari | 10+ | ✅ Full |
| Edge | 79+ | ✅ Full |
- GPU Dependent: Real-time performance varies with graphics capabilities
- Export Time: Increases with resolution and frame count
- Memory Usage: Multiple layers impact VRAM usage
- Mobile Support: Limited by device GPU capabilities
We welcome contributions! Please feel free to submit issues, feature requests, or pull requests.
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
- Follow existing JavaScript conventions
- Add comments for complex mathematical operations
- Test across different browsers
- Maintain backward compatibility
This project is licensed under the MIT License - see the LICENSE file for details.
- WebGL Community: For GPU acceleration capabilities
- JSZip Library: For ZIP file generation
- Wave Mathematics: Fourier analysis and synthesis principles
- Game Development Community: For real-world use case feedback
Built with WebGL, vanilla JavaScript, and lots of wave mathematics! 🌊
Perfect for game developers, VFX artists, educators, and anyone who loves the beauty of mathematical waves.