Storm Breakers : rough sea ocean engine

Storm Breakers : an ocean engine specialized in simulating rough seas, designed for gameplay.

For Unity 2021.3+, in URP (maybe upgradable to HDRP)

About me

Hi everyone, I’m a French engineer, passionate about seas, waves and boats. I always wanted to play video games with good waves, but was only disappointed with existing ones. So I decided to do something about it ! After observing for years waves in real condition (doing body surfing and sea kayaking) and learning about the science of waves (I have a brother who did a thesis about sea waves), I eventually gathered enough knowledge to write a new ocean model that will suits my desires, and I hope you’ll like it too !

It will be a customizable asset instead of a game to reduce ambition, still I’m not a pro game developer, I’m basically learning Unity through this full time project. So you can’t expect something as good as Crest for example. But I intend to include in this asset something that I couldn’t find anywhere else : realistic waves designed to be playable, allowing to create new game mechanics (storm survival, extreme surfing). I’ll get back to this major point later in the post.

By the way, if you are interested in sharing the adventure with me, I am open minded to partnership !

About the asset

This asset is called Storm Breakers because it is suited to render and simulate physics with breaking waves in stormy deep waters. This will also be able to render a calm ocean, but it might not be as good as existing assets. This asset will not be suited to render and simulate breaking waves on the shoreline as they are very different waves (this I intend to code it later if I get successful enough with this asset).

This asset is not an accurate scientific ocean model at all, but it is largely inspired by real world physics. I’m using science only to reduce tweaking, and I simplify most of the scientific models I need for performance purposes.

I’m designing this asset for gameplay purposes mainly, not that much for high definition rendering as I have no good graphic skills at my disposal.

In this thread I will explain all the things that I feel are important for both the game creators and the players, including some explanation on my ocean model. Basically the thread post will consist of the documentation of the asset. I will also post about the update in the development of the asset. I will be open minded to suggestions and criticism, especially for Unity usage as I’m not a professional !

Feature list
The main features that I plan to include in the first release :

  • Vertex shader to animate the ocean with realistic and playable waves. (completed)

  • Descent surface shader. (to be done)

  • Extended ocean controller. (done)

  • Simple ocean controller. (to be done)

  • Buoyancy interaction with the ocean. (almost completed)

  • Particles system to simulate breaking wave and make dynamic texturing on the water. (to be polished)

  • Particles systems for the interaction of object in water, make dynamic texturing on the water. (to be polished)

  • A hull generator so you can tweak the behavior of a boat through realistic physic. (to be done)

  • A camera controller that you can tweak the motion sickness. (to be done)

  • A simple gameplay I’ve been thinking about so you can directly play with the asset. (to be done)

Then if I get successful enough, I plan to code some additional features :

  • Baked wave system to improve performance.

  • Underwater camera simple effect.

  • Procedural water sound. (I have some ideas how to do it.) Do you feel it should be a main feature ?

  • Rogue waves (you will want it for your game, I know it ^^ ) and ocean local tweaking (for example the effect of a reef).

Gameplay

So I’m making this asset for gameplay purposes, after all we are here to make games right ?

There are many mechanics in the real ocean that inspired me for game mechanics. The objective of this asset is to share them with you.

First of all, even if the stormy ocean looks like complete chaos, waves are actually predictable, yet not obvious. Once the patterns based on physical phenomena that I will explain clearly here and in the documentation are learnt, the player can read the ocean to anticipate the waves. This is more difficult with the Gerstener model because it makes too many waves overlapping in too many directions.

Waves can be like enemies in your game. That’s what we expect from a 15m-high breaking wave : danger. And I will make sure that a boat will capsize if steering badly onto the breaking waves.

Waves can also be your friends, that would be especially true if your game consists of surfing waves. This is possible in this model because waves exist for a time long enough to be rode with a boat. Adding this to the fact you can predict them, but also taking in account the fact that it is daring to surf big waves, this should make for a hell of an extreme surfing gameplay.

Last but not least, most of the gameplay would be based on the satisfaction of seeing tons of water particles, providing the same experience to the video watchers of ships in storms. I hope I’ll do something good enough for your eyes !

Global architecture

For the global architecture of the asset, I choose to copy the math of the ocean model 3 time: one in C#, one in shader graph and one in VFX graph. I know this is bad programming practice, but this also leads to a very forward computation, which is easier for newbie like me, and I think it is more optimized.

All the 3 codes are a bit different in some points as to how they manage breaking, but are otherwise rigorously exactly the same for the rest so they can be synchronized without any callback. It means for example to handwrite a random function and make a fully deterministic ocean model.

The ocean model math is computed a lot. So any change on the ocean model math will have drastic change in the overall performance. At first, I’m coding everything analytically as it helps me move fast without having to learn baking techniques. Then when the overall asset will be settled, I will go by baking texture to improve performance and allow more complex game mechanics on top of the asset.

Project state

Today I’ve reached the milestone of the proof of concept, meaning I’ve successfully implemented the most innovative features with decent performance : custom ocean model, breaking waves VFX, dynamic water texturing using both VFX graph and shader graph (this is full of Unity latest experimental features), and realistic buoyancy physics (which needed to be coded my way to better integrate the rough sea phenomena).

Here are some screen shot :

The next steps in the project - after receiving your feedback - will consist of less innovative but more rigorous coding (not my best). I will be full time on it.

That’s it for today, next time I will talk a bit about my ocean model !


6 Likes

Some update in the rendering.

Nice work!

The Ocean model

I have developed my own ocean model for this asset. The main reason is because existing models are not suitable for rendering the phenomena I wished to include. Indeed, FFT or Gerstner model might be based on real world spectrums, they are limited by their linearity and the fact that actual waves are not infinite but local and random.

My model is based on 4 major novels modeling techniques :

  • Waves are grouped in sets.

  • Big wave erases the smaller one.

  • Wave shape adjusted at high intensity.

  • Breakers VFX.

I will explain a bit about those features as they have a noticeable impact on gameplay and require some more tweaking than usual ocean engines, but also for your own personal culture :slight_smile:

  • Waves grouped in sets

I coded a behavior that is very well known by surfers, yet not much applied in rendering techniques, is that the waves travel in groups, or sets. This becomes especially true in agitated water where the waves are very local and with a low number of waves per group.

Most of the actual rendering techniques use the addition of many infinite and permanent waves. The first images show an ocean with infinite waves, and the second shows the grouped waves of my model. In both cases there are 4 wave systems.

Coding waves in groups has a lot of impact on the visual realism, but also on gameplay. This is why it is important to understand this point, for both the game creator and the player.

Surfers are used to see sets, or groups, of a dozen waves, the ones in the middle being the bigger ones. This is applicable for an old swell that traveled thousands of km in the ocean, but what about right in the middle of the storm ? This is still true but the groups have much fewer waves, my observation showed that actually the number of waves in a group are between 1 and 3 in agitated waters. Then as the groups of waves travel, their wavelength increases, their amplitude decreases, and their number of waves increases up to a dozen or even more.

One very important phenomena is that the group itself doesn’t travel as fast as the wave it contains. In deep water, the group speed is at half the speed of the waves. This has many consequences :

First, it explains why we can’t track down a wave from A to B. This is because a wave always dies in front of the group, leaving another one in the back of the group. In the middle of the group the wave reaches maximal amplitude, this is where it is likely to break. So the waves are predictable because when you spot a big one, you can track down its group that will generate other waves of the same kind and you can steer your boat accordingly. The pattern is readable yet not intuitively obvious, which can be valuable for gameplay. If you look at this video, you will see that a large breaker is always followed by another large breaker :

The way I coded the groups is by making an amplitude map over each system (kind of a voronoi but simpler), this map moving at half speed of the wave. This map also applies an unphasing on each group to break as many visible patterns as possible. Thanks to the features this map provides, it is not required to have many systems as the other rendering techniques do, but calculating the map requires a bit more computation time per system. Currently, I have chosen to use only 4 systems and I feel it is enough for most use cases while maintaining the tweaking parameters as low as possible (there are 5 parameters per system that I will clearly explain later and in the documentation).

In the first picture we can see a single system of groups with about 2 waves, in the second pictures we can see groups of about 4 waves (and with a smaller wavelength) :

2.Big wave erases the smaller ones.

In reality waves cannot be too high, there is a point when breaking occurs which limits the height to about 0.17 the wavelength in deep water. This is still true when waves add to each other, but the small one is the one that will lose its height by spilling all its water out. This means that large waves - which move faster than the small one - erase almost everything on their way (directionally wise). Only the small ones that build fast enough with the wind can be found behind a large one in the same direction.

One of the major consequences for gameplay is that in a storm with insane waves, there are places without many waves. I coded this thanks to the group’s localization (plus the disappearance of small waves into the larger ones) and it makes a very different sea than with the Gerstener model that uses permanent waves. The times without much waves can provide the player the ability to read the ocean or attend to his boat. It also emphasizes the surging of the big waves that are in contrast with the rest of the sea.

In this screenshot we can see both a quite calm sea in the background and large breakers in the foreground.

In this other screenshot with the point of view from a boat, we can spot a large breaker looming ahead that contrasts with the rest of the visible sea.

3. Wave shape

I also reviewed the traditional way of coding waves as circular trajectories of water particles. This is quite realistic for calm waves and very convenient with the use of cosine and sine that are periodic, but it fails in rendering high intensity waves. The first picture shows an ocean with the classic circular trajectories (and the groups) and the second how I adjusted waves shapes. We can see (but it’s quite subtle) that the waves have a more flat steep and a more curved crest like a horseshoe, which is more realistic.

The overall shape might be more realistic, the actual water trajectory is not. I increased the horizontal displacement to almost the point of infinite compression at the crest, so as to make a natural tessellation in the mesh that renders the ocean, thus avoiding the crest to jitter. The counterpart of this technique is that the speed of the water in the trough of the waves might look too fast for seasoned eyes. Also I had to make sure that the mesh doesn’t self intersect at any point when waves add to each other.

4.Breakers VFX

The major feature required for rendering rough seas is obviously the VFX that renders the sea foam bursts when the wave breaks. Well I’m not going to explain a lot about it, just the fact that their speed, size and position are calculated according to water horizontal compression and the wave’s size, which correspond to what I currently understand about the physics of breaking waves.

To code this I use a first level of VFX graph that reads roughly the sea state on grid-based positions. Those invisible particles create a burst of more particles on a sub-grid-based position when a trigger is activated, and these particles come alive when a second trigger is reached on their position. Then the live particles are given size, speed and position and they render the burst of sea foam. Those particles create in turns floating sea foam particles that texturate the water (using shader graph vertex displacement to follow the waves). I might explain this better later as I will let you tweak all of this, and even improve it (I will only obfuscate a bit the ocean math).

For next time I’ll prepare a video showing off all the sea states possible with the model.

4 Likes

Can we test, or buy maybe? :slight_smile: looks nice.

Hey thanks ! I’m planning on making a small demo, but it’s not ready yet.

1 Like

Already looks great visually and very functional!
There are two things I think could round it up though:

  • Some reflections of the water surface. It looks a bit matte at the moment. In the right angle, water sparkles!
  • Some depth effect would enhance this. Especially with waves, when our eyes look pretty straight into a water surface (like the side of a wave) we can actually see through the surface. Some random mist below the surface with the surface itself being slightly transparent could achieve this effect. Maybe there is a shader-only solution too.

Hey thanks for the comment. I realized that my shader was in a specular workflow which prevented me from setting the right smoothness, and thus reducing the reflection. I corrected this and it’s seems better :

Still I haven’t coded anything special for the shader, only the basic shader graph PBR. It might require some more writing that is outside my skills. Also the normal map is still temporary.

As for the water transparency, I’m not sure that I will do it because it adds a lot of extra work that I might be bad with (this is my first Unity project). Also I feel it doesn’t make much sense in deep water, in reality we don’t see many things through the sea water. Still I understand that it is likely to become a request from the user, so I might plan this after the first release.

In any case, most of my package will be open and easy to modify. I think it is possible to include the excellent shader of Crest for example, which is something I will try.

2 Likes

Hi !:smile:

Some updates about this asset. I’ve made this video so you can see various possible sea state made with my custom ocean model :

Also a bit of a gameplay that can be made : a fishing boat caught in the middle of the storm.

For the project, I’m struggling with some graphic and art production : beautiful VFX, transparent shader, underwater camera (I actually have no idea how to do it).
I might code the sound of the breakers to change my mind, it’s the last big work that I did not start.

When the VFX will be improved, I’ll show you how we can surf 10m high waves :sunglasses:

Hi !

So I coded procedural audio, at least for the waves and boat splash. For the wind it will come a bit later, I’m still thinking whether to make it fully procedurally (hard and probably expensive) or by modulating a recorded audio clip (less possibility to tweak according to the weather).

The way I did this is by modulating a pink noise audio clip with low pass filters and gain that are hand written in a OnAudioFilterRead. Because it is likely that there are more breaking waves than hardware audio channels, all the wave audios are generated through a single audio source and filter (and not through several game objects). This means I had to hand-write audio spatialization too, it still lacks some good spatialization though.

The sound saturates quickly when big waves break near the camera. I don’t know how to solve this issue without having to lower the overall wave volume and raise the speaker volume to very high values. Or maybe the code needs more tweaking.

For the next steps in the projects, I still feel quite limited with graphics, so I might start baking some wave data to improve performance. I hope this will unlock some resourceful techniques to improve graphics (more particles to make them less obvious, denser mesh to make 3D ripples). But I’m afraid that as far as I am alone, this project will consist of features lacking quality, no matter how cool they should be.

4 Likes

Is is amusing! When will the shelves in Asset Store?

Hi everyone,

I’ve implemented the wind audio, I did this by simply modulating the volume and pitch of a audio clip I’ve made procedurally in Audacity. Also I reworked some other feature like the breaking force of the wave, ripples normal texture, sea foam VFX, and I improved the graphics with a bit of subsurface scattering (without actually coding the path of light through the water, it’s just emission function of the waves).

(Play it loud !!)

This last improvement settled the main feature I wanted to implement for the first release. So starting from now I will focus on cleaning the code and improving the user interface and aim for a first release in the asset store (in a month or two). But before this I will make a small playable demo so you can try it and give first feedback ! The gameplay will consist of the same sea state and boat as in the video, I will add buoys so you can try to reach them without sinking, or you will just go windward and try some surfing !

2 Likes

What is the plan with this, like a an adventure game or similar? Just curious?

For now the plan is to make an asset including small gameplay but not a full game, that will be up to you !

Yet I have tons of ideas to make games out of this ocean physic : racing against a storm, extreme surfing with custom boats, survival in the ocean, sailing race, etc ! If I can’t find partnership I won’t be able to do it myself, so perhaps I’ll just write the ideas in the documentation of the asset.

1 Like

Hi everyone,

I’ve released a free playable demo for this asset !

Download at Storm Breakers by The Storm Rider

Have fun !

3 Likes

Hi everyone,

I’ve published a new video showing off the water rendering in a clear environment. This video also shows how scalable the whole code is (physics, VFX, audio) against larger ships and smaller waves. I’ve added the reflection of dynamic objects (the ship) by setting a reflection probe in a mirror position from the main camera relative to the water plane. This is a rough approximation when there are waves, but the effect is subtle enough so we don’t see the aberration.

Yet I’m likely going to put this project aside for an indeterminate time. Indeed I don’t feel fit for the next steps ahead : debugging, cleaning, and most notably selling. I’ll wait to find a partnership to help me tackle those last steps.

2 Likes

Is there anyway we could get breaking waves, as shown in the image below?

8506652--1133162--download.jpg

Hi N0tTh3Pr0 sorry I forgot to answer you. Not in this ocean system. This one is designed for deep water waves and such plunging waves are impossible in those condition, so I didn’t try to code that.
Yet I’m trying very hard to code true breaking waves in shallow water like you show. My approach is to make the waves break function of the depth with complex (but direct) math function. I’ve got some results but it still very far from making a nice rendering and I’m not sure this approach will lead anywhere.

So eventually I get back to the project ! here are some video of the current rendering :

With a reworked particle system :

The project is almost ready, writing the documentation and preparing the examples. Stay tuned !

2 Likes

This is actually amazing, great job!

Thanks !

So for the demo I plan to include 4 examples showing off different possibilities with my package. here are some early footage.

  1. Fishing in deep blue sea : showing off what the ocean model is optimized for.

I think I need to tweak the audio to remove some white noise from the ship buoyancy, and maybe set the sound of the breaking wave a bit louder. Apart from that this is very close from the final rendering.
The 3D model of the ship won’t be included in the package as I don’t have the commercial license, but it is downloadable for free and I’ll provide the link. The engine audio won’t be included either.

  1. Sailing in the sunset : showing off calm water and the achievable beauty of the water.

I need to add a bit of post processing to make the environment more beautiful. I can make the sails move with a cloth component, but is it worth it ?
The skybox cubemap and the 3D model of the ship won’t be included because of the license issue, but they are both downloadable for free and I’ll provide the link to download them.

  1. Surfing giant waves : showing off the possible game mechanic with the waves.

Well there isn’t yet the giant waves in this video, I’m still working on the speedboat physics. I solved most of the issue we see in the video : boat rising up too much, unstable trajectory. There is one last thing to be coded, it’s how to make the speedboat corners well and leans in the wave while surfing, and I think I just understood how this physics happens in real life ! I’ll try to code this and I will post a new video with real surfing if it works. That would be quite an innovation useful for any speedboat game.
The speedboat 3D model will also not be part of the package but downloadable for free, as well for its engine audio and the skybox.

  1. Surviving the storm : showing off how dangerous we can make the sea.
    Well it’s the video from my previous post, I need to work more on it to make a better feeling of storm.
    Both model are paid asset form the asset store, but the ship is not anymore available and I can’t contact the seller.
2 Likes