Computer generated water has always interested me, since the days of POVRay on Amiga I was trying to simulate it in some way.
Some days ago, while studying another technique, I put everything aside because in that particular moment I felt the urge to implement a water shader. 😀
I began looking for existing implementations and I found Reimer’s XNA tutorial, a simple approach which I think could be optimized, but that already provides a nice looking water.
The technique is composed of four passes:
- Rendering the reflection map
- Rendering the refraction map
- Rendering the scene
- Rendering the water plane linearly interpolating the two maps with a Fresnel term
One of the drawbacks is represented by the fact that the whole scene is rendered three times during the first three passes, I’m sure that this procedure could be optimized, but I was lazy enough to cease any further test. 🙂
Moreover having every pass clearly separated helps with debugging and makes the application capable of displaying them one at a time.
The scene is rendered with parallax mapping enabled, and that is more evident than ever thanks to the new bricks textures, but with an altered shader that also performs user plane clipping, decisive for the first two passes.
Talking about the Fresnel term I have implemented a naive (nothing more than a dot(V, N)) and a better approximation based on the Nvidia’s Fresnel reflection paper.
In the source you will find both but only the first one is actually used, it works better in the scene used in this demo.
You can easily see that waves are fake, the water is composed of just two triangles, the ripple animation is generated by the fragment shader altering texture coordinates based on a normal map and using a time variable.