Brainstorming: Simulating beach waves

I’m looking to simulate shallow water with waves breaking on a beach. It doesn’t need to be accurate or respond to physics in any meaningful way, it just needs to look good and get players in the mood.

One look at the asset store and you’ll see dozens of shaders made for rendering water and even a few that say they’re for ocean rendering. Most of these will talk about reflection, refraction, and underwater fog.

None of them look anything like this:
7849581--995661--upload_2022-1-28_11-42-27.jpeg

Or this:

Or this:

Mirror for first 30 seconds of 2nd video if you can’t see YouTube:

I don’t see anything under the water; refraction and underwater fog don’t apply. The reflection is so diffused we don’t even need to think about planar or screen-space reflections; it could basically be replaced with a single color, possibly attenuated by distance from the camera to fade from blue to a slightly darker blue. The only salient effects are the rolling waves themselves, spray and foam – and there is a LOT more spray and foam in a shallow water/beach simulation than in a deep ocean.

The first thing you’ll find on a search is NVIDIA WaveWorks: NVIDIA WaveWorks | NVIDIA Developer . This is a bit out of my price range for an indie developer. Also, all the demos/videos appear to be for deep-water simulations; if you’re trying to do a boat it would work fine, but the foam generation looks kinda wonky and the videos are very careful to never show a beach scene. And here’s why…

So back to the drawing board. Anything involving simulating every particle (SPH) feels like a no-go; you’d need to use way too coarse a grid to get playable frame rates, which wouldn’t scale to a whole beach scene. So what if the actual water simulation is done separately from the foam/spray? This thread here extensively discusses the rolling motion and shape of the waves themselves, and appears to be a decent model of that action:

That covers the large-scale wave deformation, but not the spray and foam. Most of what I’m seeing does particles for the spray (the alternative would be raymarching like volumetric clouds do but I don’t see a compelling reason to do that). Using particles for the foam also seems like an option. Here’s a very blurry video from 2010:

Sadly, I can’t seem to find much more info on that technique, because it looks really very good. That’s exactly what I want.

Another option I saw somewhere (can’t find link) was to use a 2D Navier-Stokes simulation on a texture for the surface of the water to simulate foam and project that over the actual wave surface as a foam density map. The issues here are how to properly spawn and dissipate the foam as well as modelling the undertow of the wave pushing and pulling the foam. If anyone has any links to something like that, I’d love to check them out, although it might end up being a “play with it until it looks decent” sort of thing.

A final option might be to use wave-particles:

I’ve prototyped that before (for a pool, not an ocean), so would be easy for me to port to Unity, then somehow integrate the vertex-based rolling waves and the foam/spray. The tricky part is that “somehow”; how would you generate the particles on the edges, or turn the WP collisions into actual foam that could be rendered, and places to emit spray particles? However, this gets the small details of the surface and collisions with rocks/surface outcroppings in a way that’s reasonably scalable, which is not necessarily true of the other techniques (Navier-Stokes isn’t cheap at all but the smallest scales), so it could look good both close up and far away.

Ultimately, I don’t know how worthwhile it is to pursue this. Since so many commercial games seem to ignore this, perhaps it’s an intractable problem with today’s hardware, or just so expensive to render that the rest of my jungle island would need to be a single billboarded sprite so the beach would look good ;-P. But if anyone has any other ideas or can point me to some specific, detailed info about how they achieved something like this, I’d love to hear your thoughts. I want big, crashing waves with huge foamy sprays, not weenie little gerstner waves disappearing into the sand.

Yes, it’s still a intractable problem.

Yes it would be so expensive to render you would just have one beach.

Breaking water is best done using a particle based method like spherical hydrodynamics or position based dynamics. Both are still very expensive for large numbers of particles even on todays hardware.

implementations are quite common. These are old methods but PBD seem the preferred dues to its ease to interact with other scene objects and its stability.

AI ‘assisted’ methods are also appearing and might be the way of the future but its still early days.

anyone who spends some time trying to write and optimize something like this quickly comes to the conclusion computers are just not up to the job quite yet. At least not for real time large scale applications.

2 Likes

I just checked your Git projects and you definitely know what you’re talking about! Sounds like this just won’t work in a physically accurate way in realtime.

Thinking some more about this, I wonder if a semi-baked approach might work. The large scale could be done using PBD or SPH and exported as a low-res animated volume texture with motion vectors or a vector field. This would handle the waves crashing against shore terrain, varying heights of the beach and underwater, large rocks, etc. You could bake several loops*, maybe one for calm/low tide and one for a massive storm.

But unless you want to bake 100 GB of volume data, it would be quite low detail, even for a moderate beach size (say 1km long). However, that (plus some noise) could be enough to drive large-scale mesh deformation. Then you’d do some kind of grid around where the camera is and have an additional sim going on in realtime for the high-frequency details. WPs on the surface could capture these sorts of details in a 2D heightfield:

7852224--996363--wave.gif

Again, the issue is foam and spray, though. Even if you have reasonably accurate wave height data, how would you transform what’s basically a heightfield plus some motion vectors into actual spray and foam that looks dramatic and interesting instead of some foamy textures applied on top of the water?

  • (getting simulations to loop sounds like a massive PITA; I remember working with looping fires in EmberGen last year and how difficult that was – and that program actually has tools to make that happen. Could maybe use a multi-second lerp that kinda sorta lines up with the wave frequency and tweak it until it’s not noticeable)

In that video you linked that you said you liked, they aren’t actually simulating concave waves at all. It is just like he said, a heightfield simulation, a spray/foam particle system, and a two-way rigid body coupled system (not really relevant atm).

The heightfiled simulation shouldn’t be too hard as there are numerous articles online about it.

The particles I think could be done as a PBD or SPH simulation with some “artistic” choices for how they are generated, like when the heightfield velocity changes quickly (would happen from collisions).

I think you wouldn’t need a ton of particles to make it look nice. Especially if you can get a bit fancy with how the particles are rendered (different orientations and sizes based on velocity or on nearby particle density).

Also the particles only need to be calculated /rendered at a nearby distance, and the heightfield sim can be calculated over a much larger distance.

1 Like

As joshuacwilde mentioned the distant detail is best done with height fields.

I have heard about people baking the breaking waves and I think there is a asset on the store that does this.
I dont know much about animation but its sounds like a lot work and data to bake. Would have to be small areas and repeated a lot.

SPH/PDH models simulate the spray the same way as the water with a few tweaks. Never simulated spray before so dont know all the details.

People often resort to these mixed approaches and blending them altogether is hard but not impossible.

You will obviously need some sort of mesh for the ocean surface. This seems simple but is actually extremely hard
as the high level of points you need to get good detail becomes a problem. The grid in Ceto was the most complicated part and was a lot of work to get right and even then still had many limitations.

Then you would need to blend in those over features and it starts to get complicated quick.

There’s also fluid-implicit particle (FLIP) that’s worth looking at.

1 Like

The simplest thing you could do is something like this, just less toony:

Have a decent displacement / wave formation (look into gerstner waves?) and spawn good looking foam particles at strategic places and times.

1 Like

If it’s something you’re still contemplating, I think one of the best vfx-based water today is KWS water. According to his trello board he’s considering implementing breaking waves too. He’s making great effects, so putting together sprays and whatnot certainly wouldn’t be a problem. Maybe you can contact him to see if you can strike a deal with him. The worst case scenario is he says no.

1 Like

Yeah; this is the part I’m most scared about, since I haven’t seen many really good implementations of that which run at playable framerates, and no idea at all about how to render it in a convincing way that doesn’t look too “billboardy” or wispy like a lot of spray particles do. Hmm… I’ll noodle a bit more. I wonder if using a few different flipbooks would look good and provide enough variety or if it would just look like mist and not spray:

Good idea about using velocity deltas as points to spawn particles.

This could cover the spray, what about the foam? Just particles that are advected by the velocity of the heightmap so they move along the water surface? I’m trying to avoid the “texture foam” look that a lot of games have:

7852848--996492--upload_2022-1-30_3-5-6.png

You’re not kidding :hushed:

Out of curiosity, did you investigate punting the mesh generation to the GPU and using tesselation? Theoretically, you can get an approximately even pixel-to-tri ratio.

I took a quick look at that (there’s a neat blender plugin which uses that), but that only really seems appropriate for offline simulation or maybe a small-scale voxel field.

Gerstner waves are fine for deep water simulations, but don’t look much like the beaches in those videos. They basically simulate water with an infinite depth, which is fine for deep ocean sims and good enough for calm bays/lakes, but don’t really look realistic for a true shoreline feeling. And the little sprays there are the kind of gamey look I’m trying to avoid – it looks fine for that cartoony style, but I’m going for something more realistic like:

7852848--996495--Animation.gif

Thanks!!! Definitely the best-looking water asset I’ve seen! I’ll keep an eye on it and see if it evolves as far as foam, spray, and wave breaking are concerned.

1 Like

Kinda but decided it was over kill. The projected grind already had enough vertices. The issue is was that vertices position on the surface can vary dramatically based on how the camera moves. Made tweaking it so it works for everyone’s camera style a pain.

If I was to do again I would go with a planar or spherical grid with tessellation and I would just stick to small waves.

1 Like

The idea of tessellation is you can determine edge factors in the hull/patch shader and have different tesselation levels for stuff close to the frame than far away from the camera (and do some extra culling). I was thinking about not managing grids at all besides “big MxN plane that covers the camera view”. So camera style shouldn’t matter (other than the swimming vertex issue). But you’re limited in which platforms you can target.

I can see grid management becoming a MUCH bigger issue with simulations, though, if you want to manage the simulation scale dynamically. Meshes can be regenerated per frame and are not stateful. But if in one shot the camera is looking from a distance and the next shot is from the POV of a turtle on the beach, there could be some massive discontinuities unless the entire beach is being simulated at the same resolution every frame.

Anyways, Liqui-Gen has gotten me all excited, so maybe that’s the solution for spray/splashes.