Sign in to follow this  
DanielH

Water fading out near the shoreline?

Recommended Posts

Hello. I'm doing a little game where I need to render some simple heightmaps with a little lake or something like that once and a while. The look of the water I want is that it should be in a plain blue color, but near the shoreline it should fade nicely to transparent so it would give the appearance of shallow water. I also want small waves going towards the shorelines. But I have great problems achieving this effect and I've made several approaches so far that haven't worked out at all. My last and simpliest approach so far only involved to try to fade the water near the edges. I just made the waterplane like a flat heightfield with colorable points and then colored the points belonging to the quads in the heightmap that intersected the waterplane. Looks horrible.... And another problem I get while doing this is that depth test isn't working good at all for the waterplane <-> heightmap. Why is that? See this screenshot: http://henell.com/daniel/water.jpg I really need guidance to achieve nice looking water! :)

Share this post


Link to post
Share on other sites
You may do like this:

1) render scene depth-info (not including water!!!) w/o any textures and so on, only naked triangles, without blending or alpha test. This is done in twice-speed on modern hardware. After, save this Z-info into a texture (via glCopyTexSubImage2D or via FBO, however you want to)

2) render your whole scene without water

3) render water, and in pixel shader get the difference between renderable fragment and that, stored in depth texture. Note, that it is not linear! After, modulate your water fragment transparency due to that difference (by formula in PS, or by look-up in 1D texture, no matter)

Share this post


Link to post
Share on other sites
A less elegant but easy solution is to use simple per vertex alpha blending.

First draw the terrain as usual. Then set the render state so that the source fragment is weighted by its alpha value, and the destination fragment by one minus the alpha value. Then tesselate the water so that the triangle density of the mesh is not too sparse around the shore (or you could just draw a mesh of quads). When specifying the colour of each vertex, calculate the difference in height between the ground and the water, and use this (maybe after scaling it) as your alpha value. This could be pre calculated.

This method isn't as accurate as Jackis', but it still looks good and it's easier to set up and code.

Share this post


Link to post
Share on other sites
One more solution!

For every water patch (whole closed water area) you might compute transparency texture on preprocessing. I mean, you enclose all this water patch by rectangle, and linearly map this rectangle to texture. After, for each texel of texture map, you map it to corresponding water point, evaluating it's transparency, as heightfield difference function, and store it in a texture.

This method negliges you to subdivide all your water areas to rectangles (as mentioned above), and render them with transparency function as simple texture look up! This is more accurate, that MumbleFuzz's method, cause it's not per-vertex based (MumbleFuzz's method is highly depends on water tesselation).

I think, that for your planar water with such a landscape geometry, as in screenshot, is the best solution, because my first method requires ps2.0 (or arb_fp1 in GL) pixel shader version (GeForceFX+ or Radeon9500+ hardware required).

Good luck! If any questions - I appreciate to help you!

Share this post


Link to post
Share on other sites
You're in dire need of a fresnel term, for one thing. Compute the dot product of the water's normal and the water->camera vector; when it's 1, render transparent, and when it's 0, render opaque. Interpolate between the two accordingly.

When you render the heightmap originally, you could also fade vertices to black/blue as they go down beneath the surface of the water, simulating the fogging effect you get underwater.

As far as how to implement that goes, use shaders.

Don't make the water part of the heightmap - you need that section of the heightmap to represent the geometry beneath the surface of the water.

Share this post


Link to post
Share on other sites
Actually I have already solved my problem with a solution almost the same as the second one Jackis suggested! I did it with a texture, a texture animation even and got some nice waves going towards the shore :) Looks very neat for have been done by me, usally my stuff don't look this good :D

Share this post


Link to post
Share on other sites
http://henell.com/daniel/water2.jpg

What do you think? Please give me all suggestions you have for makeing it look better! :) As for shaders, I have never used them and I have barely any knowledge about it. Where can I read up about it?

Thanks!

Share this post


Link to post
Share on other sites
looks nice

if you are interested in simulating more optical properties of water then you should add some hints towards refraction and reflection, as these are good visual clues to the nature of the surface.

the usual cheesy kludge way to do this is to render the _inverted_ world to a texture, render the refracted world to a second texture, and use a shader to weight between these textures (which are projected back into the scene)

the weighting uses the "fresnel term" which you can google.

i have a small demo + source of these effects at
http://people.umass.edu/rwhall
if you are interested I will help you understand the code, but what you should know is that this trick is not physically accurate, just a cheap way of parameterizing an effect that has too many variables to do properly...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this