Since I couldn’t find a water shader, that suited my needs, I decided to make my own one. The problem with mobile shaders is to find a balance between good looks and high performance.
Here’s the latest update:
EDIT:
I’ve decided to expand the project, so now there’s multiple quality levels from low to high for different types of applications and devices, so I’m not trying to limit things to mobiles. I’m trying to make everything as flexible as possible. All of them now have optional shore foam, depth based transparency and realtime dynamic reflections. I’ll go from the lowest to the highest:
The low quality shader has only one color, and a slight depth based transparency.
Two different colors (for deep and shallow water) with slight depth based transparency for the simulation of realistic water absorption. Everything works pretty okay on mobiles up to this point.
The difference between this one and the previous one is, that this shader does the actual color absorption. It also has real refraction, to make the transparent part of the water distort the visible ground. Color absoprtion and refraction though, will bring most mobile devices down to their knees, except for the most powerful ones, but it shouldn’t be a problem for future generations.
Added a second normal map for the wave textures. The two wave textures now blend over each other, to make the specularity look more natural and less repetitive.
At some point I decided to deform the mesh, so see if the shader plays along and YUCK - it looked awful! That was mainly, because up to this point the shaders didn’t really have a solid surface. All the surface shows is the specularity and the distorted reflections. That’s quite enough for quiet waters like lakes or basins, especially in RTS-like games.
So I decided to create a second shader with more bumpy surface:
It has 3 textures for waves, that blend smoothly into each other, depth based transparency, shore fade, refraction, distance fade on the shore foam, to prevent the tiling from becoming ugly at long distances and of course the realtime reflection.
This of course goes way beyond mobile capacities, especially because it’s a PBL shader. But I’ve decided to see, if I can strip it of some things, that are not vital and see, if I can get this one in an acceptable quality for mobiles.
So I decided to use this shader as a basis for an ocean. The next step was, to see how the shader plays along with waves. For testing I simply animated a mesh based on a sine wave with noise.
Of course a simple sine wave doesn’t come close to Gerstner waves, so it’s very far away from being realistic. But the shader seems to deal with the deformation pretty acceptably.
The next step will be to find a way to simulate more realistic waves. I’m not yet sure, which approach I’m gonna use, because there’s multiple ways to do that, from very simple to overly complicated (guess it’s gonna be something in between). After that, the shader will need to be adjusted to behave depending on vertex positions to get foam and partial transparency on the more choppy parts of the water. But it’s still quite a way to go.
I wonder if I should already post the surface shaders on the asset store, even before I get the waves to work, there’s a lot of people who don’t need waves after all. But on the other hand, the asset would feel kind of incomplete.
What do you think?