开发者

Trying to create water ripple effect, but the ripples turn into squars in OpenGL

开发者 https://www.devze.com 2023-02-02 10:30 出处:网络
I\'m using the water flow algorithm I got from http://www.gamedev.net/reference/articles/article915.asp

I'm using the water flow algorithm I got from http://www.gamedev.net/reference/articles/article915.asp

It seems like when I create a wave, it start out as a circle. As time passes the circle dissipates and has lines at 45, -45 45 and -45 degree angles. So it no longer looks like a wave, but a square-like shape.

This is the code to start the wave:

WaveMapPingc(int x,int y,int rd, int str)
{
    for(float a=0; a<3.14159*2; a+=.1)
    {
        for(int r=1; r<rd;r++)
        {
            //   LowWaveMapPingca(x+(int)((float)r*cos(a)+.5) ,y+(int)((float)r*sin(a)+.5),str );
            WaveMap[CT]
            [x+(int)((float)r*cos(a)+.5)]
            [y+(int)((float)r*sin(a)+.5)]=str;
        }
    }
}

This is the code that generates the height map:

UpdateWaveMap()
{
    int x,y,n;

    int Temporary_Value = CT;
    CT = NW;
    NW = Temporary_Value;

    // { Skip the edges to allow area sampling }
    for(y= 1; y<MAXY-1; y++)
    {
        for(x= 1;x< MAXX-1; x++)
        {
            n = ( WaveMap[CT][x-1][y] +
                  WaveMap[CT][x+1][y] +
                  WaveMap[CT][x][y-1] +
                  WaveMap[CT][x][y+1] ) / 2 -
                WaveMap[NW][x][y];

            float sub=(float)n / DAMP;
            int isub=sub;

            if (n<1 && isub==0)
                n++;
            els开发者_JAVA百科e 
                if (n>1 && isub==0)
                    n--;
                else
                    n = n-isub;
            WaveMap[NW][x][y] = n;
        } // x
    } // y
} // function


You're using integers for the positions. This introduces all sorts of quantization problems ( for the vertices positions, that is.)

I'd say you likely want to keep it in floating point to make things smooth.


I know this effect from my very first ripple simulation. Solution: Use a more detailed convolution kernel. You may also want to add a damping factor, to dissipate the ripples, so no numerical errors accumulate into a runaway integration. This is the relevant part from one of my early game engines (wrote that one 10 years ago):

*value_at(Next, x, y)=(
  (
    (*value_at(Current, x-1, y-1)+
     *value_at(Current, x+1, y-1)+
     *value_at(Current, x+1, y+1)+
     *value_at(Current, x-1, y+1))+

    (*value_at(Current, x-1, y)+
     *value_at(Current, x+1, y)+
     *value_at(Current, x, y-1)+
     *value_at(Current, x, y+1))
  )/4
  -( *value_at(Previous, x, y) )
)*0.98;

Effectively this is computing a discrete wave function using a convolution. The higher the resolution of the kernel, the better the quality. Using SIMD optimization really helps here. However since a convolution is simple multiplication in fourier space, it's a very good idea to do this thing using a fourier method if you're interested in high quality ripples and waves. Using some tweaking one can produce also nice gravity waves (not to be confused with those from general relativity) http://en.wikipedia.org/wiki/Gravity_wave

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号