The techniques used in this are based on the ones found in GPU Gems by NVIDIA.
Water simulation is a common challenge in not only just game development, but any form of graphic development.
Accurate fluid simulation is computationally heavy and often over-kill for the effect that most people desire.
While there are a number of unique solutions to this challenge, the one I’ll be demonstrating here is known as the “Sum of Sines”.
What is the Sum of Sines?
The Sum of Sines in this case is exactly what it sounds like, the addition of multiple different sine waves in a vertex shader to mimick the effect of waves in a body of water.
The equation of this can be demonstrated in this scary looking formula:
Where:
Creating the Shader
To demonstrate this concept, let’s look at the process of creating this shader for Unity.
1 Sine Wave
To begin, lets start with just a single sine wave in the x direction:
Applying this shader to material and attaching to a basic plane gives us a result that looks something like this:
So far so good! The sine wave gives us a super simple wave over the mesh of our plane.
Fragment Shader
However, we currently are just passing in the UV for the fragment portion of the shader,
lets change it a bit to make it look more like water.
Now it’s looking a bit more like water.
Summing Sines & Direction
Now though, our water is just going in the “x” direction and looks a bit too simple. To fix this, we can implement the dot product of the direction vector with our vertex x & z.
Additionally, we can create 3 different variable sine waves and add them all together.
This is our final product:
For a simple water shader, this looks pretty good for how cheap of a shader it is. However, there’s of course more than can be done.
Additional Implementations
”Bottle-Necking the Wave”
The waves at the moment look a lot like an upside-down “U” at the moment, which while fine for the look I was going for, isn’t quite realistic.
To change this, we can implement another variable “k” and modify the equation like so:
This will pull in the neck of the wave, creating a more natural looking wave.
Conclusion
For simple fluid simulation for large bodies of water, such as an ocean, this shader is light-weight and effective enough for more basic implementations.
However, this method is not great for more realistic water simulations.