I am trying to create the effect of the water surface thickness with a vertex-fragment shader.

I am in a 3D game environment but It's a scroll view so a "2D" view. Here is a good tutorial of creating such effect in real 2D using fragment shader.
But this can't be used in my case I think. For the moment I have only a plane were I apply refraction.


And I want to apply the water thickness effect. But I don't know how to do it.
I am not trying to create some water deformation/displacement using vertex for the moment, this is not the point.

I don't know if it's possible with a simple quad maybe should I use an object like this.


Here are some examples.

1 2 4 rayman

I don't have any idea on how to create this effect.

Thanks a lot !

[EDIT] Added Rayman water effect to have a better reference of the effect.

  • \$\begingroup\$ How are you doing your water effect currently? If the first screenshot in the post is yours, it looks like you're drawing a 2D quad over the scene, with a shader that distorts it. If that's correct, why can't you follow the instructions in the tutorial, which is also based on using a distorted 2D texture? \$\endgroup\$ – Nathan Reed May 28 '13 at 16:38
  • \$\begingroup\$ I have a 3D quad with a vertex-fragment shader that distords the background (the background is captured by Unity GrabPass functionnality). I don't think that using a 2D texture is a good idea, I was thinking of something more generic with customable parameters but it seems there is no other way... and it would be slower no ? \$\endgroup\$ – MaT May 29 '13 at 6:56

Have a value in the shader that specifies wetness. Smaller than 0 means air, greater than 1 means water, and in between means meniscus.

Here is some pseudo code:

vec2 uv2 = bigWaves(uv); // modify the texture coords to create a wavy water effect
float wetness = (uv2.y - 0.1) * 100;

if( wetness<0.0 )
    gl_Fragment = texture2D(screen_texture,uv); // is air - no refraction or effect
else if( wetness>1.0 )
    vec2 uv3 = smallWaves(uv2); // modify the texture coords to create a ripply water effect
    gl_Fragment = texture2D(screen_texture,uv3); // is water - with refraction
    gl_Fragment = vec4(1,1,1,1); // solid white meniscus

This is the simplest I can make it. If it were me, I would do something a bit more complicated to antialias the meniscus and apply more refraction there or something, but I can't tell you what because it would take aesthetic iterations. Also, I would tint and blur the water sample. But I'll leave all that up to you.

  • \$\begingroup\$ Yes, it's a good idea ! I totally agree about blur and tint. I am also adding a depth(Y) gradient (maybe another depth(Z) gradient). I should add a different refraction effect in the meniscus zone too but for the moment I am trying to have a ripple effect like in Rayman. But I don't know how. Maybe I should use different Textures for the meniscus to have this duplicate effect. I don't know if you know what I mean. \$\endgroup\$ – MaT Jun 3 '13 at 10:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.