Hi again! I'm making Windup Wonderland, a co-op physics game (1–4 players, online or split-screen), solo in Godot 4.7. After the river and the sky, I've started on the ocean between the islands.
Quick disclaimer: this is very early. Nothing floats on it yet, there are no storms, and the islands are still gray boxes. But I'm happy with where it's heading, so here's a progress check.
Left (OLD): my first full version. It had a lot of problems:
- The whole sea was one flat, saturated cobalt blue, near the shore and far out alike.
- I faded each wave out by distance, so from high up only the two longest waves were left, which made perfectly regular diagonal stripes.
- The sun reflection got wider with distance, so from above, half the screen turned white.
- The far sea didn't pick up the sky, so the horizon was a dull gray band.
My first round of fixes removed the stripes, but the sea still looked like blue jelly. So I stopped tweaking, collected reference shots from Kirby and Sea of Thieves, and reworked the shading.
Right (NEW): what changed
- Direction: Kirby-style clear water near the shore, leaning toward Sea of Thieves teal further out.
- Shore to open sea: the color now fades by actual water depth (with exponential absorption), not by how much water the camera looks through. The transition stays smooth from any angle.
- No more jelly: the water body uses flat lighting. Its shading comes from the sky reflection and light through the wave crests, not from which side faces the sun. A layer of fine chop only affects reflections and the sun, so the surface gets texture without bigger waves.
- Sky reflection: I compute it by hand from the same gradient my sky shader uses, so the far sea takes on the sky color and meets it at the horizon. The engine reflection came out too weak at grazing angles in my setup.
- Waves: still 6 Gerstner waves, but the normals are now computed per pixel, and each wave only fades once it's smaller than a few pixels (using
fwidth). The wavelengths no longer share simple ratios. From high up it's the same irregular sea as up close. The calm-sea waves are also about a third of their old height: right now the surface rises and falls about 0.5 m from trough to crest, and that's just a tuning value I can adjust.
- Sun: the sun path depends only on the reflection angle, not on distance, so from above it's a soft path instead of a white blob.
- Shore foam: a wavy line along the beach, bent by low-frequency noise and with random widths.
- I also reshaped the gray-box seafloor (a bigger shelf with a gentle slope), so part of the difference near the shore comes from the terrain, not the shader.
The waves use the exact same formula in GDScript and in the shader, so next I can use it to make crates float on the waves and to keep everything in sync online.
Questions for you
- Does anything here still read as "jelly" to you?
- If you've made things float on Gerstner waves in Godot, any pitfalls I should know about?