Water fragment shader for vertical surfaces proposal


#1

Hello the great JME community. I checked the under water effect on JME but the results was:
Imgur
I checked the water fragment shader and I could make few changes to this:
Imgur
I know that my changes makes the water shades a little messy but at least there is no bleeding on the vertical and almost vertical surfaces.
The change is:
On “Common/MatDefs/Water/water.frag”:
on Caustic part we have (line 216):

#ifdef ENABLE_CAUSTICS 
     vec2 windDirection=m_WindDirection;
    texC = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time  + position.x) * 0.01;
    vec2 texCoord2 = (position.xz + eyeVecNorm.xz * 0.1) * 0.05 + m_Time * 0.05 * windDirection + sin(m_Time  + position.z) * 0.01;
    caustics += (texture2D(m_CausticsMap, texC)+ texture2D(m_CausticsMap, texCoord2)).rgb;                  
    caustics=saturate(mix(m_WaterColor.rgb,caustics,m_CausticsIntensity));            
    color=mix(color2,caustics,m_CausticsIntensity);
#else
    color=color2;
#endif

Which can be changed into:

#ifdef ENABLE_CAUSTICS 
    vec2 windDirection=m_WindDirection;
    texC = (position.xy + eyeVecNorm.xz * 0.8) * 0.05 + m_Time * 0.012 * windDirection + sin(m_Time  + position.z) * 0.042;
    vec2 texCoord2 = (position.xz + eyeVecNorm.xz * 0.8) * 0.05 + m_Time * 0.013 * windDirection + sin(m_Time  + position.y) * 0.041;
    vec2 texCoord3 = (position.yz + eyeVecNorm.xz * 0.8) * 0.05 + m_Time * 0.014 * windDirection + sin(m_Time  + position.x) * 0.043;
    caustics += (texture2D(m_CausticsMap, texC)+ texture2D(m_CausticsMap, texCoord2) + texture2D(m_CausticsMap, texCoord3)).rgb;
    caustics=saturate(mix(m_WaterColor.rgb,caustics,m_CausticsIntensity));            
    color=mix(color2,caustics,m_CausticsIntensity);
#else
    color=color2;
#endif

However, this doesn’t work well on terrain, some patterns can be seen and there are some stretches on different slopes.
Original:
Imgur
Revised:
Imgur
But I think it can be improved with some playing with the shader.
Maybe the dev team can consider this change into the future releases. Thank you for the great game engine.


#2

Looks great. Someone with a GitHub account should create a pull request. You, perhaps?


#3

While I agree that that caustics look a little silly on vertical walls in the existing shader, I don’t think the change is very realistic, either.

Really, where caustics appear and don’t appear, are stretched and not stretched, should be based on light direction. They really will stretch down the wall at the right lighting angle.

Edit: I remember seeing this during many a lazy summer afternoon when I was a teenager, as my friends and I lounged at the bottom of the public pool for a minute+ at a time trying to see how long we could sit there.


#4

perhaps reduce intensity based on angle, sharper angles = stretching = less intense ?


#5

Thank you all for your feedbacks. Another solution can be fading the caustics on the vertical surfaces and under the objects but I have no idea how to do it. It has to be something to normal vectors of the triangles. I’m not good in shaders but I think fading solution can be a better solution compared to mine.
Let me give you more details of what I inspected:

  • The original shader has one pattern on xz plane.
  • The changed effect has 3D patterns. Which means that a pattern is for xy, another is for xz and another for yz. Each pattern in its 2D plane has impact on the other planes. That’s why it is more noisy. For instance the pattern of xz has different impact on xy and yz planes. Actually, the patterns are not exactly on xz, xy or yz planes, because if each of them be on one plane, they will introduce ugly lines of the original shader to other planes. The patterns are on tilted surfaces between xy, xz and yz so that they never introduce ugly parallel lines to any side of a model.
  • Currently, the wind direction is broken. Because mainly I wanted this for a water container and I didn’t want wind direction.
    Therefore, understanding how the patterns from several planes may mix together, can help on resolving this issue.
    A test on a sphere:
    The original:

Imgur
The revised:

Imgur
If you look carefully you see different patterns which are for different planes. If the wind direction could be solved, then it may have potential to be a pull request.


#6

I don’t have experience on repositories and collaborative communities like this. Is it possible to have a pull request for a test scene like “TestPostWater” so that others can see the difference themselves and be able to play with it?


#7

But, for example, there should really be no caustics at all on the bottoms of those spheres.

Caustics are not really a 3D texture. They are projected by (generally) a single light source (the sun)… but a single light simulation would be better than nothing… and better than a 3D texture.

Edit: and by the way, with the current “sun always directly up” caustics, one need only dot the surface normal with the up vector to see how much of the effect to apply. I don’t know what that means in the case of this shader since it’s a post-proc shader.


#8

Yes, you can submit a pull request for TestPostWater.


#9

You are right. Also the caustic should stretch a little on almost vertical surfaces but not parallel lines on complete vertical surfaces. I try to work around the normal product and see what I can get.