Попытка создать эффект водной ряби, но в OpenGL рябь превращается в квадраты - PullRequest
1 голос
/ 06 января 2011

Я использую алгоритм потока воды, полученный из http://www.gamedev.net/reference/articles/article915.asp

Кажется, что когда я создаю волну, она начинается в виде круга.С течением времени круг рассеивается и имеет линии под углами 45, -45, 45 и -45 градусов.Таким образом, он больше не выглядит как волна, а имеет форму квадрата.

Это код для запуска волны:

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;
        }
    }
}

Это код, который генерирует карту высот:

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++;
            else 
                if (n>1 && isub==0)
                    n--;
                else
                    n = n-isub;
            WaveMap[NW][x][y] = n;
        } // x
    } // y
} // function

Ответы [ 2 ]

1 голос
/ 06 января 2011

Вы используете целые числа для позиций.Это вводит все виды проблем квантования (то есть для положений вершин.)

0 голосов
/ 06 января 2011

Я знаю этот эффект по моей самой первой имитации пульсации.Решение: Используйте более детальное ядро ​​свертки.Возможно, вы также захотите добавить коэффициент демпфирования, чтобы рассеять пульсации, чтобы никакие числовые ошибки не накапливались в быстрой интеграции.Это релевантная часть одного из моих ранних игровых движков (написанного 10 лет назад):

*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;

Фактически это вычисление дискретной волновой функции с использованием свертки.Чем выше разрешение ядра, тем лучше качество.Использование SIMD-оптимизации действительно помогает здесь.Однако, поскольку свертка - это простое умножение в пространстве Фурье, очень хорошая идея сделать это, используя метод Фурье, если вы заинтересованы в высококачественных пульсациях и волнах.Используя некоторые настройки, можно создавать также хорошие гравитационные волны (не путать с таковыми из общей теории относительности) http://en.wikipedia.org/wiki/Gravity_wave

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...