Jump to content
• Advertisement

# Water depth visibility

This topic is 3629 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

## Recommended Posts

http://images.gamedev.net/gallery/57bb6e0484924ccfb511f3caf38b2154_water_shot1_big.jpg I'm struggling to achieve a similar effect as in the picture above. the visibility decreases as the the terrain goes deeper underwater. I need a good tutorial/example.

#### Share this post

##### Share on other sites
Advertisement
Vary the transparency of your water based on the depth difference between the water fragment and the screen Z-buffer entry at that screen-space position. You should be able to fetch that easily enough. Remember that depth is usually stored in logarithmic space, so you'll need to convert the number you read from the depth buffer into a linear-space figure.

#### Share this post

##### Share on other sites
I know the principle but not the exact implementation.

get depth value
do something with it
lerp reflection, refraction

#### Share this post

##### Share on other sites
In my engine Typhoon I simulate refractions with an additional render pass, by rendering the underwater scene to a texture from the current point of view. The shaders used for this pass take into account water attenuation.
Let's call C the color of an underwater point P, before attenuation. C is attenuated exponentially according to the optical length travelled underwater by a ray from the viewer V to P. In addition, light is scattered along the viewing path by underwater particles. A simplified formula for the final color is:

l = uw(|V-P|)
fex = exp(- a*l)
C' = fex*C + (1-fex)*D

C' is the final attenuated color, l is the underwater distance between the viewer and the point P, fex is the total light attenuation, a is a wavelength-dependent coefficient and D is a diffuse radiance term representing the in-scattered light.

In short, the further the point P is from the viewer, the more its color tends to D.
The formula is a simplification because it does not take into account visibility terms and the phase function and other subtle phenomena, but it should suffice for your purpose.
You can find a physical derivation for the parameters a and D in the reference paper Rendering Natural Waters

When you render water, you fetch the reflected and refracted scene from the respective textures. Then you have to blend them according to the Fresnel term, evaluated per pixel. This is described in many articles about water rendering (including my article in ShaderX 3 ;) )

Do not hesitate to write me back for further clarifications if needed.

Stefano Lanza

#### Share this post

##### Share on other sites
Doing depth transparency with the methods discussed can be superficially acceptable in some situations, but is really quite fake.

A more correct approximation will also use a depth buffer, but will instead reconstruct the x,y,z worldspace position of each below-water pixel (as described many times on this forum, usually in contex of deffered rendering).

Then depth is calculated by biasing the y distance of the pixel from the water surface.

This way opens the doors to a much more optically correct water surface, becasue water depth should affect transparency equally at *any* distance from the camera. This means the fresnel effect will have more and proper influence at arbitrary distances.

That is, if viewed directly overhead the fresnel effect will be minimize reflection, allowing more transparency in shallow water at any camera height (imagin looking down on the ocean from an airplane).

So to sum up, depth transparency should not be view-dependent..only fresnel is view-dependent. Obviously this isn't exactly correct but it works.
..............................................................................

A more specific implementation:

1) render a depth-pass to a floating-point texture before rendering the water

2) use a method to reconstruct the xyz world position

3) calcuate water depth as the distance form worldspace.y to waterlevel

4) bias or "normalize" this value to give you a greyscale gradient...it should be black at the water level and fading to white at the deepest parts (it doesnt matter which is black and which is white, can just reverse the lerp order)

5) Then use the depth value to create the "base" water color..that is: choose a water color based on a macro-texture or a set variable...lerp this color with the refraction texture.

6) Then lerp in the reflection texture using the fresnel value. Fresnel can be easily approximated by dotting the water surface normals with the view position.

Many tweaks will be needed, and I assume you know how to make and project the reflection and refraction textures, and do the waves and stuff..

hope this helps, realistic water is a big deal and and can make a scene look awesome. It took me many tries to get water i am mostly happy with..

#### Share this post

##### Share on other sites
Quote:
 Original post by Matt AufderheideA more specific implementation:1) render a depth-pass to a floating-point texture before rendering the water2) use a method to reconstruct the xyz world position3) calcuate water depth as the distance form worldspace.y to waterlevel4) bias or "normalize" this value to give you a greyscale gradient...it should be black at the water level and fading to white at the deepest parts (it doesnt matter which is black and which is white, can just reverse the lerp order)5) Then use the depth value to create the "base" water color..that is: choose a water color based on a macro-texture or a set variable...lerp this color with the refraction texture.6) Then lerp in the reflection texture using the fresnel value. Fresnel can be easily approximated by dotting the water surface normals with the view position.Many tweaks will be needed, and I assume you know how to make and project the reflection and refraction textures, and do the waves and stuff..hope this helps, realistic water is a big deal and and can make a scene look awesome. It took me many tries to get water i am mostly happy with..

You could alternatively do steps 1-4 in the refraction pass, storing the normalized lerp value in the alpha channel, and eliminate the extra pass. This is one way that I have done it.

#### Share this post

##### Share on other sites
Quote:
 Original post by glaekenYou could alternatively do steps 1-4 in the refraction pass, storing the normalized lerp value in the alpha channel, and eliminate the extra pass. This is one way that I have done it.

However, the way i do it, I dont do a refraction pass as a seperate pass..I just grab the back buffer (before rendering the water) to a texture, then project that using a bumpy offset in the final water pass. Since I use a deferred pipeline, there is no extra pass to eliminate that is not already neccessary.

#### Share this post

##### Share on other sites
I may be missing the point, but it seems by looking at the picture that volumetic fog could achive a similar effect.

#### Share this post

##### Share on other sites
Quote:
 So to sum up, depth transparency should not be view-dependent..only fresnel is view-dependent. Obviously this isn't exactly correct but it works.

Wrong. Water transparency depends on the optical length between the viewer and the observed point, so it IS view-dependent. This is obvious when the viewer is underwater, less above.

The correct approach to handle water attenuation for underwater objects, actually consists of two different steps:

1) Attenuate the incoming light (usually sun, sky and caustics) travelling from the water surface to the illuminated point; add a depth-dependent term to account for the in-scattered radiance too.

2) Attenuate the light reflected by the point in the direction of the viewer, as I described in my previous post.

These concepts apply to the lightning of underwater objects seen both from above and underwater.
Above, and especially for a game, you can cheat by considering only the depth underwater and ignoring the dependency on the viewer and the light attenuation, but it is not physically correct (although it might look acceptable).

You can use a refraction pass or a deferred pass, depending on your rendering pipeline. With a refraction pass you can have interesting effects like stretching the scene (to simulate the bending of viewing rays due to refraction) and a modified field of view. A deferred rendering on the other side has other advantages, in fact I'm gonna try it for my new water renderer.

Ciao

Stefano Lanza

#### Share this post

##### Share on other sites
I still cant get the job done, I need some examples. simple shader perhaps?

#### Share this post

##### Share on other sites

• Advertisement
• Advertisement

• ### Popular Contributors

1. 1
2. 2
Rutin
24
3. 3
4. 4
JoeJ
16
5. 5
• Advertisement

• 14
• 29
• 11
• 11
• 9
• ### Forum Statistics

• Total Topics
631773
• Total Posts
3002265
×

## Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!