Article : Realistic Soft Edged Water In XNA
That’s it! Enjoy your new awesome planar water, all in shader 2.0!
Performance Considerations
While this sample doesn’t go out of it’s way to slow things down, it isn’t exactly optimal. There are some thigns you could do to potentially speed things up. The biggest overhead for most people in a game situtation would be having to render the scene 4 times. Currrently we render scene depth, scene color, and water reflection to render targets, in 3 separate sets of draw calls, prior to a fourth set of draw calls to the backbuffer. Fotunately, we can reduce those first 2 sets of draw calls to just a single set using MRT (Multiple Render Targets). This would mean that each shader rendering a scene element would also have to render its linear view depth to one of the render targets, as well as its color, so a custom shader would be in order.
Without MRT, the depth target could possibly use a half precision float, or perhaps packed integer format to save memory and speed things up. I have found that it is rather hard to keep acceptable precision for the shoreline though.
Another way to speed things up would be to reduce the size of the reflection render target, if lower resolution reflection was acceptable.
The water shader itself could also have some more microoptimizations, moving a few calculations to the vertex shader since there are a few more TEXCOORD registers available to interpolate results along. You would probably want to do this anyway if you are pixel shade limited.
Taking it Further
What if you want to do more? Sure, there are plenty more things you could do. The first and most obvious one would be to enable rendering underneath the water. When the camera Y position is less than the water plane Y position you would need to flip the cullmode to draw the back of the plane.In such a scenario the shader could do without reflection, depth colors and shoreline blending. In addition to a modifer water a shader, you would probably want a post process shader to shade things blue (or whatever your deep color was) as well as add a ripple effect.
There are more things you could do with the shader, although doing so would likely push it to shader 3.0. First is taking multiple refraction samples around the current offset pixel and averaging them to perform a box blur. You could also use a second normal map at a different scroll speed, perhaps going in the opposite direction. Such a normal map would be best if subtle, or complements the original normal map.
Download the sample: Here

May 6th, 2010 - 20:22
Finally, a subject on just water and not necessarily ‘adding’ water for Xna.
I am going to try this out as my goal is to just do water itself in Xna, for now.
May 20th, 2010 - 17:52
This is very similar to the technique I use to render water as a post processing pass. In my implementation I render geometry into the stencil buffer and output linear view space depth. Then run a full screen quad over the results of that to produce the water in the back-buffer with stencil rejection enabled.
July 13th, 2010 - 00:52
Hey,
is there a way you could re-upload the sample and images for this tutorial? Would be really nice.
BTW this is just the tutorial i’ve been looking for for months … thank you soooo much
July 14th, 2010 - 17:26
Existence – Fixed the images and sample download.
July 21st, 2010 - 17:32
Hey Sarge,
The pixel shader broke when I ran this under Xna 3.0. Band-aid solution: saved the pixel shader to a static variable before executing begin command with the Effect, then set it back once it went to null. Is there a quick fix to get around the ravages of Microsoft progress?
Best,
Dave
July 22nd, 2010 - 13:06
Nota bene: my previous fix didn’t really work. If you receive the debugging message about not having a valid vertex or pixel shader, then you will probably have to set the pixel shader device version to 2 in the .fx file, instead of 3.
July 22nd, 2010 - 14:47
This sample doesnt seem to work for me it causes problems with the for loops:
for (int x = 0; x < Tesselation-1; x++)
it underlines the ‘;’ after -1 and the ‘)’