Physical Ocean Surface - Developing a Realistic Water Shader

This shader is now available on the Marketplace!
You can find the documentation in the wiki.
Here is a link to the support thread.

Below the told WIP post:

The last few months I have been working on a water shader, mainly to learn shader programming. All my work has been focused on getting a realistic surface motion. I’m now at a point where the surface is starting to look liquid enough for my taste.
Since I don’t have a real use for the shader, I want to make it available on the Marketplace once it’s finished.


0578ae93fd4a3d5b52631048cf6a7e00d1c0187b.jpeg](Physical Water Surface - Unreal Engine 4 GIF by theokoles | Gfycat)

3782b6baac72cf7e689cfb82df0a6125364c3405.jpeg](Physical Water Surface - Unreal Engine 4 GIF by theokoles | Gfycat)

58446af49e977e6caacf233de4ecbc3a9e586d93.jpeg](Physical Water Surface - Unreal Engine 4 GIF by theokoles | Gfycat)


For the next video, I replaced the water material in the Vehicle Game example with my water shader:



I use the JONSWAP wave spectrum to generate parameters for Gerstner waves. The user needs to provide two parameters as input: Wind speed and fetch. From these parameters, the corresponding JONSWAP spectrum is created and used to sample Gerstner wave parameters (this part is not implemented outside of UE4). The list of wave parameters is imported into UE4 and used as input for the Gerstner equations.

The advantage of this approach is that you automatically get physically correct Gerstner wave parameters. No matter which wind speed and fetch you chose as input, you will always get a good looking surface motion.
I’ve implemented the dispersion relation for gravity-capillary waves, so it is possible to generate large ocean waves or small capillary waves with wavelengths of millimeters or anything in between. The motion will always be correct.

Is anyone interested in having this released?
I think I can provide an ocean surface that works out of the box. Just place it in your map, set the values for wind speed and fetch and you will get surface motion like you see in the video above. There is still a lot of work to do, but I think it can be done.

To do / feature list:

  • Automatic buoyancy for simple objects DONE
  • Automatic buoyancy for arbitrary objects DONE
  • Read Gerstner wave parameters from csv file DONE
  • Generate library of csv files with wave parameters for different combinations of wind speed and fetch length DONE
  • Make the water plane follow the camera to simulate an infinite ocean DONE

I think this would be great if you released it! :slight_smile:

I have improved the look of the surface. This video has foam and a normal map for fine surface details.

Amazing!! Are you planning to release it in marketplace or for free?

If you’re interested in working on it and don’t mind releasing it then why not?

I’d enjoy it =]

My current plan is to submit it to the marketplace.
The most important feature that still needs to be implemented is an easy way for the user to change the wind speed and fetch values that are used to generate the waves. Right now the wave paramaters need to be manually imported into the blueprint.
I also want to allow tweaking the quality of the surface motion. This will affect the number of individual Gerstner waves that are summed up to create the effect. In the videos above, 170 Gerstner waves are summed up with periods varying from 8 seconds to 0.5 seconds. I think that the number of waves can be reduced quite a bit while still looking good.

Are you going to do the underwater treatment as well? Caustics?

I think what we’re all looking for is something similar to GTA V’s water. :wink:

Good work!

At the moment transparency is not implemented.
In the video below a different normal map is used to create fine surface details. I will try to replace this normal map with capillary Gerstner waves in the future. The video also has improved water color and shows sun reflections.
I’m using the BlendAngleCorrectedNormals node to blend the Gerstner normals and the the additional normal map, but this turns out to be quite expensive. I will explore other ways to blend the normals to improve performance.

I have implemented a first version of buoyancy (at the moment only a single point is evaluated for each object). Buoyancy is implemented as a component, this means that you can drag any static mesh into the level, add the Buoyancy component like this:


and the object will float:


The Buoyancy component automatically calculates the center of gravity of the object and makes it move with the water surface.

Here is a large screenshot because Youtube compression eats all the detail:

Looks awesome! Would it be optimal for this system to be place around a open world map, or is it too performance heavy?

I agree this is really great but could you implement an LOD system so we can use it in bigger scenes with a larger view distance?

I think it could be possible, but it’s difficult for me to say how good the performance is because my graphics card is quite old. I have a XFX RADEON HD6870 Black Edition. Using a water plane with 32000 triangles and 16000 vertices, I get 25 fps in worst case at 1920x1080 resulution and epic quality settings when I launch the level in full screen. Please keep in mind that I have done barely any performance optimizations.

Yes, I will make the water look good from large view distances.

the appearance is good but the flow do not look naturally

Hey, will it be released soon? Or a demo?

Yes looks good, for starting. But know the heavy things, a nice shore with foam and reflections.
Just sayin ^^

The main feature of my shader will be the high quality, easily configurable surface motion. The shader will have basic foam/surface color similar to what you can see in the videos above to get you started, but I’m spending most of my effort on implementing the surface motion and making it easy to use. I’m new to graphics programming. I know how to implement the equations for the surface motion, but I don’t know how to make the surface foam and reflections look super realistic.
Right now I’m working on getting the CSV to Blueprint import working. When I can quickly import different wave parameters, I plan to show videos with different ocean conditions.

At the moment I’m in the process of changing how the material paramters are set and processed. Now the editor crashes reproducibly when I connect two material functions in the water material. So I’m waiting for 4.8 to see if this works there.

At the moment I’m still working on converting the shader to 4.8 without the editor crashing. Releasing a demo is a good idea, maybe I will do that.

Hello ,
is it possible to download now your fantastic Looking Ocean-Demo somewhere?
Kind regards,

I’m still in the process of converting to 4.8. Also, I’m making it possible to directly import csv files with wave parameters via blueprint. Additionally, I’m trying to further simplify all the equations to improve performance. When this is done, you can expect a downloadable demo and new videos.