Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 20

Thread: Water surface rendering

  1. #1
    Junior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    St. Louis, MO USA
    Posts
    181

    Water surface rendering

    Hello.

    I have been doing some research on water surface rendering, and I am having great difficulty finding good information on it. What I am primarily interested in is the coloring and lighting effects on the water surface. Also, I have two restrictions: the renderer MUST NOT use pixel shaders, and it must not require an extremely finely tesselated mesh.

    Probably the best source is the Gamasutra article by Jensen and Golias, which most people who are doing water rendering seem to be aware of. The link is http://www.gamasutra.com/gdce/2001/jensen/jensen_01.htm .

    I have a few problems with this article. First of all, I dont have a degree in mathematics, and when they start using the Greek letters, well.. its all Greek to me. Not to mention, I havent studied differential equations. The other problem I have with it is that it is largely theoretical, and does not discuss the specifics of rendering with a 3D API such as OpenGL or Direct3D.

    Nonetheless, the article got me really excited when it showed this screenshot: http://www.gamasutra.com/gdce/2001/jensen/fig_3,4.gif
    along with its wireframe version: http://www.gamasutra.com/gdce/2001/jensen/fig_3.5.gif . However, the author does not explain the technique used to achieve that in an detail.

    Here is another water engine I found, which is ideally what I'd like to achieve: http://www.geocities.com/davidl1_2000/index.htm . If you look at the top screenshot, you can tell that the color of water is dependent on the viewing angle. Where the angle is greater, the water is more whitish-greenish, and when you are looking directly at it, the water is more darkish-bluish, which is an important property of water.

    Finally, here is another demo I found: http://www.people.fas.harvard.edu/~reichard/water/
    His demo does not run directly out of the zip, but after making a few changes I got it to run. He uses vertex colors to make the color of the water, along with an animated bump map which appears to be calculated in real time (havent looked deep enough into the code to confirm this though). Since he uses vertex colors, the water looks really great for a finely tesselated mesh, but looks terribly blocky for a coarse mesh. His demo also accounts for the fact that water looks more blue when looking directly at it, and more white-green when looking at it at an angle.

    At this point, I dont have a specific question, but I am hoping someone can lead me in the right direction (discuss techniques, or point me to a website). I have not made up my mind on any particular technique. What I want to achieve is a realistic coloring/lighting of water surfaces that will work with a coarse mesh and doesnt require pixel shaders. Also, it must account for the view dependent nature of water coloring (e.g. more blue when looking directly at it, more white-green when looking at an angle).

    Many thanks in advance.



    [This message has been edited by ioquan (edited 09-10-2003).]

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Mar 2001
    Posts
    3,768

    Re: Water surface rendering

    What I want to achieve is a realistic coloring/lighting of water surfaces that will work with a coarse mesh and doesnt require pixel shaders.
    Well, you're not going to get it.

    Realistic water requires complicated computations. Now, you can either do this via vertex programs running on a finely-tesselated mesh, or you have to resort to relatively complex per-fragment operations. Even simple bump mapping techniques require some form of moderately complex per-fragment ops.

    You say that you aren't willing to use pixel shaders. Which OpenGL extensions precisely are you wanting to avoid? You can do some pretty good stuff with NV_register_combiner or ATI_fragment_shader. Even ARB_texture_env_combine can do some interesting stuff, especially with the crossbar extension.

    In short, what tools are you allowing yourself?

  3. #3
    Junior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    St. Louis, MO USA
    Posts
    181

    Re: Water surface rendering

    My video card is a GeForce 4 MX, which does support GL_NV_register_combiners. However, I'd like to avoid using that because it is not supported on ATI cards, and I dont want to have to write completely different renderers for different cards. GL_ARB_texture_env_combine would be fine since it is supported on most cards (though I'm not sure what it does). GL_ATI_fragment_shader is totally out of the question since my hardware doesnt support it and I wouldnt be able to test it.

    I should clarify when I say "realistic". I dont mean something that is a perfectly physically correct model. I mean something that looks reasonably good. Even if I decide to use fragment programs or something later, I still need to be able to render water without them. I want to get the best looking water possible without them.

    You say I will not be able to achieve the results I want without pixel or vertex shaders. However, one of the demos I posted above does not use any vertex or pixel shaders, and achieves excellent results (however, it does use a very fine mesh). If I recall correctly, even Waverace 64 for the Nintendo 64 had good looking water (but its been a while since I've seen it, so I'm not sure).

    At this point I'm basically working on the minimum renderer; something that I can be sure will work on most cards and will produce good results. I think there must be a way to obtain results close to the ones in the demos I posted above without pixel or vertex shaders.

    [This message has been edited by ioquan (edited 09-10-2003).]

  4. #4
    Intern Newbie
    Join Date
    Oct 2001
    Posts
    32

    Re: Water surface rendering

    An idea that springs to mind is to use a technique similar to celshading.

    Compute the dot product of the vertex normal and the normal from each vertex to the eye position.

    Use this value as a lookup in a 1d texture. This texture holds the colors you want the water to have.

    I have no idea if this will work or how it will look but it might be worth a try.

    You can find a celshading demo over at nehe.gamedev.net

    Regards!
    /hObbE

    P.S. It will probably not be as visually stunning as the sample pictures. At least not without a pretty dense mesh.

    [This message has been edited by tobiaso (edited 09-10-2003).]

  5. #5
    Junior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    St. Louis, MO USA
    Posts
    181

    Re: Water surface rendering

    Thanks for your reply.

    Your suggestion is similar to one of the demos I posted above. The problem is that it requires a very fine mesh. With a coarse mesh, using vertex colors in such a way gives you very blocky and ugly results.

    Here is a thought that comes to mind.. maybe someone can tell me if its good. What if I were to make a cube map that has an animated texture? Near the bottom part of the cube map, it would be more white, and near the top it would be more blue. When drawing the water, I bounce rays off of each vertex to get the texture coordinates in the cube map. Because the bottom of the cube map is more white, and the top is more blue, when you are looking at an angle, you will get more whitish colors, and when looking straight down, you will get more bluish colors. One problem that comes to mind with this technique is that the water might look weird if the entire texture changes whenever the view changes. But then again, it might look really good. Any thoughts?

  6. #6
    Advanced Member Frequent Contributor
    Join Date
    Apr 2000
    Location
    Melbourne,Victoria,Australia
    Posts
    767

    Re: Water surface rendering

    The cg SDK (from memory) contained a very nice water simulation. I believe it ran entirely on the GPU so it most likely used "pixel shaders". The effect was available through the effects viewer and consisted of a rotating shape under the water (sorry, I am being kind of vague here - I don't have it in front of me). At any rate you could probably implement the same in software but performance will most likely suffer. One drawback with this method will be the colouring of your surface (the nVidia example looks more like mercury than water).

    Of course if you absolutely mustn't use "Pixel Shaders" then I believe you're in luck because I think that's an exclusively Dx term.

  7. #7
    Junior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    St. Louis, MO USA
    Posts
    181

    Re: Water surface rendering

    Pixel shaders, fragment programs, whatever they are called. Sorry if my terminology is incorrect.. I havent messed around with that stuff yet.

    Anyway, using a cube map, I managed to achieve results that are closer to what I want. Here are some screenshots:
    http://users.ms11.net/~ioquan/screenshots/envmap0.jpg http://users.ms11.net/~ioquan/screenshots/envmap1.jpg http://users.ms11.net/~ioquan/screenshots/envmap2.jpg http://users.ms11.net/~ioquan/screenshots/envmap3.jpg

    It still has a long way to go I think. The surface looks more like mercury or oil than water.

    I have a question about cube mapping. Why is it that when I use GL_REFLECTION_MAP_EXT to generate tex coords, I only ever see three of the faces of the cube map, and when I use GL_NORMAL_MAP_EXT, I only ever see 2 of the faces of the cube map? Also are there any tricks I can use that might help improve the cube mapping on the water surface? (like using the texture matrix or something)

    Thanks.

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Dec 2000
    Location
    Reutlingen, Germany
    Posts
    2,052

    Re: Water surface rendering

    DAMN! How did you do that effect? I havenīt done much about water-surfaces, but that looks pretty good, and from your statement i would think it isnīt very hard to do, is it?

    Well, about the cubemap thing. You have to rotate your cubemap acording to the rotation of the viewer. You do this by simply rotating the texture matrix of the cubemap. Either in the same direction the viewer was rotated, or in the reverse, i canīt remember, but it should be easy to find out.

    As long as you donīt do that, it is absolutely normal, that you only see 2 or 3 faces of the cubemap.

    Jan.
    GLIM - Immediate Mode Emulation for GL3

  9. #9
    Advanced Member Frequent Contributor
    Join Date
    Apr 2000
    Location
    Melbourne,Victoria,Australia
    Posts
    767

    Re: Water surface rendering

    Jan2K is right. You have to apply your camera rotations (not the inverse) to the texture matrix so that your cubemap rotates with your viewpoint.

    I would think that the reason your water looks a bit "metallic" is that water doesn't always reflect light off it's surface. If you look at the examples you gave in your original post, the closer the water is to the viewer, the less it reflects (ie. you can see into the water). And individual waves further off will also exhibit this property (on their near side).

    Presumably this effect could be achieved with multitexturing or multiple passes, but I haven't any ideas as to how it could be done. Even if you just managed the effect for "nearer to the viewpoint" rather than on individual waves. You could probably use a reflectivity mask (eg. a grayscale image that modifies the amount of reflection) and combiners - but I don't know how successful this would be (it might look worse than what you already have - or it might be too expensive for adequate performance)

    Any chance of a wireframe image of what you've done? I'm interested in how you have done the water (presumably it's bump mapping).

  10. #10
    Junior Member Regular Contributor
    Join Date
    Apr 2002
    Location
    St. Louis, MO USA
    Posts
    181

    Re: Water surface rendering

    Thanks for the info on the texture matrix. Once I do that it should look better when the camera is in motion (the cube map wont seem to follow you).

    Jan2000, the effect is not too difficult to achieve. All I did was make a cube map that represents the approximate color I want the water to be at different angles, and draw the water with GL_REFLECTION_MAP_EXT tex coord generation. Once I get my water engine to a more satisfactory state, I intend to write a tutorial(s) explainging the different techniques I used.

    rgpc,
    I think I might be able to get the effect you mentioned by adding an alpha channel to the cube map textures. Also, by using another cube map for my second texture unit, I might be able to achieve better results.

    The only texture on the water right now is the one cube map. Here is the front face texture I am using: http://users.ms11.net/~ioquan/cube5.jpg . Since I'm not rotating the texture matrix, it is always in front of the viewer. By messing around with the cube textures, I have gotten a much less metallic look. Here is a new screenshot: http://users.ms11.net/~ioquan/screen...ter_island.jpg .

    Here is a wireframe shot, along with a corresponding filled version. http://users.ms11.net/~ioquan/screen...water_wire.jpg http://users.ms11.net/~ioquan/screen...water_fill.jpg



    [This message has been edited by ioquan (edited 09-12-2003).]

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •