11/2/07

Water

I made a simple height map generator which basically just sums a set of sine curves with different directions, amplitudes, and wavelengths, creating something that looks like water. The amplitude of the waves are also modulated by the water depth by looking at the height of the terrain when computing the water height map, so that the waves will get more shallow closer to shore. Combining the water height map with Fresnel based reflection and refraction produces the nice water effect shown in the image below:



The height map for the water now takes up the same amount of memory as the terrain height map, so I might try to avoid storing it explicitly, instead computing the sum of sines on demand. This also requires some changes to the kd-tree I use for ray tracing a height map, storing the tree nodes there implicitly as well. The upshot is that the highest wave frequency would no longer be limited by the resolution of the height map.

References:
Reflections & Refractions in Raytracing

2 comments:

Photon said...

Hi,

this is Photon who you may remember from the irc a couple of days ago. I just found some time to go over your blog and it's impressive. Say, in this short you say that you do a real 3D Water surface. But I assume it does not fit for real time purposes, right?
I'd really love to get more info about the refraction and reflection of the water surface.

Keep up the good work. I'd love to see more

Best regards,
Photon.

capisce said...

Exact reflection and refraction might be hard to do without ray-tracing, but you should be able to fake it quite well with a combination of environment maps and render-to-texture. The water surface is no problem to do in real-time, in fact I based it in large degree on the first chapter of GPU Gems: "Effective Water Simulation from Physical Models". It is a combination of vertex displacement which can be done in a vertex shader and bumpmapping which can be done per pixel. The Fresnel approximation from the article on reflection/refraction is relatively cheap and should be easily implemented in fragment programs. There are lots of ways to get good looking water in real-time :)