To popular demand, today I’m going to tell you how to achieve this flat style water effect with a bonus curvature thrown into it!
The earth is round
Straight to the point, the curvature effect is in the vertex shader and isn’t a post-process effect. So if you want to have that in your game you’ll need to have the following lines of code inside every shader you want to display on the screen.
It is a pretty popular effect that you can find on casual endless runner mobile games such as subway surfer
On a side note, I think that special effects and shaders in mobile games are a good source of inspiration and are generally very effective
This allows the level designer to snap pattern pretty easily in a straight line and then have the effect wrap the vertex and hide what’s behind. So you can have a nice little runner without the pattern popping problem which was the original intent for my jam game Avion
Here is what you need in your shader:
So having that will bend anything according to the material properties, but the _Origin variable should be updated every frame to the position of your player or camera and you could just make all the properties global or make a script in your scene that will change the property of every material using the same shader like so: https://docs.unity3d.com/ScriptReference/Shader.PropertyToID.html
And then you can set whatever position you want to that ID.
You can see some cool exaggerated effects from it:
This is all made using a simple subdivided plane, you can use the unity plane.
Another cool thing about it, is if you have every object in your scene with that shader and you add one mesh without it, it will appear as if the object is moving down because the water is moving up. I’ve not yet implemented it as a mechanic in the game but it’s cool nonetheless.
To make a good water shader and give it substance you’ll need to add depth to it, this is a very popular technique so I’ll go over it quickly!
This will give you a nice depth to your water and you can fine-tune the effect with the _DepthMaxDistance. And a very cool thing you can add is the color lerp which let you choose what color will be drawn beneath the sea.
The obvious thing after that is adding the foam based on the depth texture.
I added couple of lines to the previous code. We’re just getting a different output from the depth using saturate and step which will translate into nice smooth shapes. Then we add a little distortion to it to add variety.
Again you can have a color added to it _FoamC but I just went with white.
Now we’re getting to the interesting bit of how to make actual waves and there are couple of techniques you can use to generate waves be it procedural or with textures.
I found this tutorial that explains both sine and Gerstner waves: https://catlikecoding.com/unity/tutorials/flow/waves/ /!\ Big brain maths /!\
Here are my Sine waves:
Modifying only the world Y-axis of the vertex so it’s 2D as opposed to the Gerstner waves that move in 3D.
And here are my Gerstner waves, from the Gerstner big brain maths tutorial:
Some bonus footage:
I think the latter looks way better and it’s more alive. But you can still make a great water shader with sine and a custom texture just like I did.
Some things you can add to that displacement to really make that water pop:
I use the vertex color data to lerp the color of the waves depending on world height. And then You can use this to do all sorts of things like make the foam disappear between waves etc…
In my game Avion, I use the height trick to flatten the water just underneath the plane so when it collides it’s not going into “fake” waves.
I hope you enjoyed the read, I love making shaders that take part in the gameplay and I had a blast making a prototype of it in …