Water coords in heightmap

I’m playing around with a water demo.
I’ve got a simple grid (25 by 25).

Here I update my grid with surrounding values

temp = (( s_array[i1-1][j1 + 1][2]
+ s_array[i1-1][j1 - 1][2]
+ s_array[i1 + 1][j1 + 1][2]
+ s_array[i1 + 1][j1- 1][2]) / 4) -s_arrayOld[i1][j1][2];

           temp = temp - (temp / 16);
           s_array[i1][j1][2] = temp;
	//Then Swap grids			
           for(int i = 0; i < 25; i++) {
	 for(int j = 0; j < 25; j++) {
	       s_array2[i][j][2] = s_array[i][j][2];

The only problem is, the ripples are square? For the life of me I cannot get circular ripples. I tried adding in the diagonal values around each point, but that didn’t do it either…Any of you have any insight in a way I can get a more circular ripple?


Cant see anything wrong but have a look at this site.


Game Programming Gems covers various themes, on of it is rendering water-like surfaces. It covers definetaly interresting things, though it a bit funny written and I still have probs with my english… (as you can see)

I have Game Programming Gems. I tried their approach (at least what’s in the book) and had worse results than this. Perhaps there’s some other issue other than this loop that’s causing irregular shaped ripples…

Oh, well

If you’re only sampling diagonal neighbors, your wave will be square. You’d have to sample a more circular region for a better propogation. Of course, a 25x25 grid doesn’t give you much room for that sort of thing.

Also, you might want to try doing the 8 nearest neighbors by including adjacent cells and weighting them more in the average.

You might be interested to know that I have found a way to do this with only a single buffer.
If your grid is ordered left to right, bottom to top, sample in a semicircle like this:


and at the same time modify the points that you sample, then it is unnecessary to have another buffer to store the new values in.
I probably haven’t explained it that well, but it isn’t that difficult to work out for yourself.

Instead of actually modifying your geometry,
it’s probably better to calculate the
rendered geometry based on the initial mesh
and a peturbation function which varies over
time. One function you can use is:

dY = sin((sqrt((X-Xc)**2+(Z-Zc)**2)/L+P*t)*2pi);

(Xc,Zc) is the center of the wave; L is the
wavelength; P is the phase speed over time.

You can window this function to create the
effect of a ripple that expands over time;
the windowing function should move out at
the same speed as P.

Thanks for all the responses.

I’ve played with the numbers a bit and found some interesing (but totally confusing things)

If I take the point directly above, below, left, and right of every point into consideration, I get a very nice "half circle " ripple (What happened to the other half?. There’s basically no disutrbance to the right of my ripple. I cause a displacement, and get a very nice half circle (no longer square) to the left of the displacement only.

That’s so strange.

If I take the 8 points around each point in consideration, my grid literaly blows up. Everything goes crazy.

If I sample anything more than 4 points, I get destruction to the grid.

To clarify what I’m doing…

I’ve read in Game Programming gems that if certain values become less than 1/2, unstability follows…Not sure how to interpret this.

bgl - if you do it like that you can only have a limited number of waves.
Do it the other way and you can have an infinite number. Also it doesn’t require any sin()s or sqrt()s. So it’s a lot better.

Ace_Man - if you sample more points, you have to reduce the contribution of each each point accordingly. Otherwise things will go crazy.

Wow, thanks guys!
I’ve finally got this thing working correctly.

> Also it doesn’t require any sin()s or sqrt()s

But the distance from epicenter (sqrt) is an
initialization only variable, and calculating
a sin() with a fixed frequency over time is
only a single complex-valued multiply per
time step (with periodic re-init because of
bit quantization losses).

Anyway, anything that works for you is fine
by me.