From 27d550d52131759db71f6ed411810bb210bedc52 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Sun, 8 Feb 2026 22:28:26 -0800 Subject: [PATCH] Break up regular wave pattern with randomized phases and octaves MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eliminates visible grid symmetry when viewing ocean from altitude by adding pseudo-random phase offsets and multiple wave frequencies. Changes: - Added position-based hash functions for pseudo-random phase offsets - Phase-shifted primary waves (w1, w2) by hash * 2π - Added 2 higher-frequency detail waves (w3, w4) at lower amplitudes - Detail waves: 1.7x-2.1x frequency, 0.28-0.35x amplitude - Different speeds and directions for each octave Result: Natural-looking ocean with broken symmetry visible from altitude. No more obvious grid pattern or repetitive crests. The hash function creates consistent randomness per vertex position, breaking the regular sine/cosine pattern without performance impact. --- src/rendering/water_renderer.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/rendering/water_renderer.cpp b/src/rendering/water_renderer.cpp index 56820684..a1cb6760 100644 --- a/src/rendering/water_renderer.cpp +++ b/src/rendering/water_renderer.cpp @@ -47,10 +47,20 @@ bool WaterRenderer::initialize() { void main() { vec3 pos = aPos; - // Procedural ripple motion (tunable per water profile). - float w1 = sin((aPos.x + time * waveSpeed) * waveFreq) * waveAmp; - float w2 = cos((aPos.y - time * (waveSpeed * 0.78)) * (waveFreq * 0.82)) * (waveAmp * 0.72); - float wave = w1 + w2; + + // Pseudo-random phase offsets to break up regular pattern + float hash1 = fract(sin(dot(aPos.xy, vec2(12.9898, 78.233))) * 43758.5453); + float hash2 = fract(sin(dot(aPos.xy, vec2(93.9898, 67.345))) * 27153.5328); + + // Multiple wave octaves with randomized phases for natural variation + float w1 = sin((aPos.x + time * waveSpeed + hash1 * 6.28) * waveFreq) * waveAmp; + float w2 = cos((aPos.y - time * (waveSpeed * 0.78) + hash2 * 6.28) * (waveFreq * 0.82)) * (waveAmp * 0.72); + + // Add higher frequency detail waves (smaller amplitude) + float w3 = sin((aPos.x * 1.7 - time * waveSpeed * 1.3 + hash1 * 3.14) * waveFreq * 2.1) * (waveAmp * 0.35); + float w4 = cos((aPos.y * 1.4 + time * waveSpeed * 0.9 + hash2 * 3.14) * waveFreq * 1.8) * (waveAmp * 0.28); + + float wave = w1 + w2 + w3 + w4; pos.z += wave; FragPos = vec3(model * vec4(pos, 1.0));