I'm wondering how I would go about creating a 2D water shader that is seen in this video http://www.youtube.com/watch?v=phChFfi4GOs

The water effect that limbo uses is pretty awesome. I'm not so much concerned about the waves, other articles cover that, but how can I get the..diffraction, I believe it's called, and various blurriness and how the object looks like it's moving even though it isn't (like real water).

GLSL is my target language.

But I don't have any idea on how to do the blur-like below-surface water movement effect. Any ideas?

  • 1
    \$\begingroup\$ I think it's refraction. Diffraction is weirder. \$\endgroup\$ Apr 29, 2013 at 2:03
  • \$\begingroup\$ damnit, never remembered the difference of them in physics ;-) \$\endgroup\$
    – user148459
    Apr 29, 2013 at 3:05

2 Answers 2


For refraction, you need to render the background to an offscreen buffer. Then draw it on screen. Finally you draw the water on top and pass the background texture into the water shader.

In GLSL you can use gl_FragCoord to get the onscreen coordinate of the pixel. You will have to divide by the background texture size to get the uv for the texture lookup.

Now, to have cool water refraction, you have to perturb the uv coordinate slightly. There are 2 ways: You can either use a load of sines and cosines, based on x, y and time. Or you could have bumpy normal maps and scroll them differently, summing them up, normalising and using xy of the normal vector to perturb the background sample position.

Finally, if you want to have a bit of blur there are a variety of ways to achieve this. The easiest is a simple box filter. Just sample a grid of pixels around the lookup point and get the average.

Hope that helps.

  • \$\begingroup\$ Thanks for your answer ! According to your suggestion it seems that this is a camera shader no ? Or do you render the screen and crop the good area ? Isn't it a bit heavy to render the whole screen ? \$\endgroup\$
    – MaT
    May 17, 2013 at 12:18
  • \$\begingroup\$ I am not entirely sure what you mean by camera shader. Are you using something like Unity? If so, I suggest looking at examples that do post processing effect to see how to use an offscreen buffer. Rendering a fullscreen textured quad with a simple shader is very quick. The slow part with be the water fragment shader, but that should usually only cover a small portion of the screen (I guess). \$\endgroup\$
    – DaleyPaley
    May 22, 2013 at 0:30
  • \$\begingroup\$ Yes I am using Unity 4 pro. I am actually using a fragment shader. I found a way to create transparency with GrabPass. \$\endgroup\$
    – MaT
    May 22, 2013 at 8:25

Any idea or help about this shader effect ? I found a couple of idea but I don'r know if they are great : GPUGems - Refraction


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .