N64 Quality Water...

Started by
13 comments, last by whitechaos35 12 years, 5 months ago
@mikiex
Screenshots don't demonstrate the water well, here are the files i have so far WinMain.cpp GLWater.h GLWater.cpp

[color="#1C2837"]@whitechaos35
[color="#1c2837"]I'm still looking into the method & code snippet you posted, it looks very promising but i haven't been able to implement it (I was trying all weekend)

[color="#1c2837"]@MortenB
[color="#1c2837"]I'm going to be looking into the link you posted; i will need ripples around objects eventually.

[color="#1c2837"]THANKS EVERYONE!
Advertisement

Here's a description of what we used to do back in the old days.
http://freespace.vir...ics/x_water.htm
When you've got it working you can just write some values into the current buffer for each position where you want objects to interact with the water.
This method is still used for games today when you need to get the water to ripple around objects.


o daaaaaaaamn, i havent been to that site in hella long ;-) I used to live on that site and other similar sites back in 2003-2005'ish. Talk about a blast from the past ;-] I learned how to draw lines, polygons, and do perlin noise off of that site. And their star field tutorial is still the best on the internet.
"a low level aho master like you couldn't kill me even if I let you"
I found a solution (In some old nVidia paper), so far this is acceptable for what i'm doing.
Also: Updated GLWater.cpp


#define MAX_CIRCLE_ANGLE 512
#define HALF_MAX_CIRCLE_ANGLE 256
#define RECIP_HALF_MAX_CIRCLE_ANGLE 0.00390625f
#define QUARTER_MAX_CIRCLE_ANGLE 128
#define MASK_MAX_CIRCLE_ANGLE 511
#define PI 3.1415926535897932f
#define PI_RECIPRICAL 0.3183098861837907f

float fast_cossin_table[MAX_CIRCLE_ANGLE];

float FAST_SIN(float n) {
float f = n * HALF_MAX_CIRCLE_ANGLE * PI_RECIPRICAL;
int i = int(f);
if (i < 0)
return fast_cossin_table[(-((-i)&MASK_MAX_CIRCLE_ANGLE)) + MAX_CIRCLE_ANGLE];
return fast_cossin_table[i&MASK_MAX_CIRCLE_ANGLE];
}

float FAST_COS(float n) {
float f = n * HALF_MAX_CIRCLE_ANGLE * PI_RECIPRICAL;
int i = int(f);
if (i < 0)
return fast_cossin_table[((-i) + QUARTER_MAX_CIRCLE_ANGLE)&MASK_MAX_CIRCLE_ANGLE];
return fast_cossin_table[(i + QUARTER_MAX_CIRCLE_ANGLE)&MASK_MAX_CIRCLE_ANGLE];
}

inline void SetupSinCosLookupTable() {
for (int i = 0 ; i < MAX_CIRCLE_ANGLE ; i++) {
fast_cossin_table = (float)sin((double)i * PI * RECIP_HALF_MAX_CIRCLE_ANGLE);
}
}
*removed, dumb qustion*
So, i've moved on to implementing ripples. So far This bit code causes a circular ripple in the water as one would expect.

void UpdateRippleWater() {
for (int z = 0; z < MAP_WIDTH; ++z) {
for (int x = 0; x < MAP_HEIGHT; ++x) {
float dist = distance(ripple_x, ripple_y, x, z);

deformData[x][z] = FAST_SIN(dist - timeCoefficient * 10.0f) * WAVE_Y_SCALE;

water[x][z][1] = deformData[x][z];
}
}
}


My question is i want to make the ripple temporary, like someone had dropped an object into the water.
That is have it only start in the center, move outward then calm back down.

Any ideas on how this effect could be achieved?
Thanks for all the help so far everyone!

My question is i want to make the ripple temporary, like someone had dropped an object into the water.
That is have it only start in the center, move outward then calm back down.

Any ideas on how this effect could be achieved?
Thanks for all the help so far everyone!



Every point within some radius of the impact point is going to oscillate. Points at an equal distance from the impact are going to be at the same value, which is determined by the phase at that distance and the attenuation value for that distance. A nice looking attenuation wave would look Gaussian.

If you can get the DDS algorithm I provided to work for you, then you can get phase-continuous samples for a sine wave (meaning if you want the frequency to decrease over time it will look perfect). By taking each of these samples and multiplying it by the corresponding attenuation sample, you will construct a "ripple wave". You can then map the distance from impact into a phase-lookup in the ripple table.

This solution eliminates your sine computation *for every value*, so long as you can output a sine wave from the DDS algorithm, which itself doesn't even compute sine values.

You also mention that you were having trouble implementing the DDS algorithm. Are you calling the "UpdateSineWaves" equivalent function at an exact frequency? If so, what is that frequency (500Hz, 1KHz, 10KHz)? Is this value defined as INC_FREQ? Is the accumulator variable 32 bits? If not, you need to set ACC_BITS to the number of bits. Is it unsigned (This algorithm works because of wraparound)? Is ACC_VALUES 2^(ACC_BITS)? If SAMPLE_BITS is 8, do you have a sine wave with 2^8 (256) values?

If you still can't get it to work, post what you have and I'll be happy to take a look.

This topic is closed to new replies.

Advertisement