Thursday, February 24, 2011

Rendering Waves, Part I

For the past couple of weeks I've been testing several different algorithms for water rendering. I've limited myself in terms of technology a bit because of the age of my video card (7+ years old) and to keep the user base somewhat broad...therefore...no pixel shaders or any effects like that. Yes, I can go out and buy a shiny new high-end graphics card, but again, it would ultimately limit the user base down the road because of my tendency to want to push my graphics hardware as far as I can. :-)

I started out by building a basic mesh class (jMesh), and then running various functions across the mesh data. One of the most peculiar algorithms I came across "averages" the four surrounding points to calculate the current point's height on every pass:

y0 = (y1 + y2 + y3 + y4) / 4

I'm not sure who to credit for coming up with that, but I thought I'd give it a run and see what happened.

I was surprised to see that when I randomly dropped raindrops onto the mesh, little wavelets spread out from each drop and then faded out. Soon, though, I ran into some limitations of this concept because I wanted my waves to propagate out further and (hopefully) reflect off some walls I'd set up at the edge of the mesh.

Today, however, I spent some time paging through a 1960's physics book and came across a diagram of something called a "wave machine". That, along with the explanatory text beneath the photo, gave me some new ideas. The text described the wave machine and how it worked. As a result, I changed course on my own algorithm tests and added an "angle" value each point on the mesh. Also, I let the x coordinate and y coordinate of each mesh point be controlled by output of a sine and a cosine function.

The result?

What is difficult to see in this screenshot is that the entire mesh is in motion, and it looks pretty close to what a storm-tossed sea would look like. With a little bit of coloring, and some mountains thrown in, it looks like this:

Maybe I should post a movie at some point. Anyway, this new algorithm is a cross between the sine/cosine functions my own "averaging" type function that has damping and a whole bunch of other variables to play around with.

One key design point I want to make here is that because I've generalized all this into a generic "mesh" class, it opens up a lot of new possibilities such as basic cloth simulation, erosion-generated terrains, etc. I suppose you could also use some of it for creating landscapes altered by earthquakes. One other thing I plan on testing down the road is whether this could be morphed into a semi-realistic cloud mesh for cloud banks.

No comments:

Post a Comment