Упрощенный 2D поток жидкости через поверхность - PullRequest
0 голосов
/ 28 января 2020

Я пытаюсь реализовать простой 2D механизм потока жидкости c в игре, чтобы представить ландшафтное наводнение. Я не пытаюсь сделать реалистичное моделирование c. Я хотел бы, чтобы он был достаточно быстрым, чтобы бегать в реальном времени и выглядеть достаточно правдоподобно. Меня не интересуют скорости или направление потока, просто уровень воды.

В настоящее время мое решение использует двумерный массив объектов («детей») и рассчитывает уровень воды на основе среднего уровня воды его соседей. У каждого ребенка есть уровень воды и переменная высота. Уровень воды всегда> = высота, и ребенок считается «мокрым», если уровень воды> высота. Это дает приемлемые результаты, если все начинается «dry», а уровень воды (при x = 0) со временем увеличивается. Вода «течет» по карте до сопредельной местности, где возвышение <уровень воды затоплен. </p>

Однако это не очень хорошо работает, когда уровень пограничной воды падает (например, представляет собой падающий прилив на пляже). Поскольку нет никакого потока между дочерними объектами, возникает градиент между дочерними объектами границы и теми, которые наиболее удалены от границы, и степень затопления не уменьшается. Я хотел бы, чтобы карта опустошалась, как и в обратном поведении, описанном в предыдущем абзаце.

My current solution. The boundary is along the left. Water flows into the map but does not drain out again when the boundary decreases.

Может кто-нибудь предложить другой метод или исправление на мой, чтобы произвести этот эффект? Я изучил статью Джоса Стама о динамических жидкостях для игр, но она слишком сложна для моих нужд.

func update_water():
    #calculate new water levels in each child
    var x = 1
    while x < width - 1:
        var y = 1
        while y < length - 1:
            var wet_neighbours = children[x+1][y].wet 
            wet_neighbours += children[x][y-1].wet
            wet_neighbours += children[x-1][y].wet
            wet_neighbours += children[x][y+1].wet

            if wet_neighbours > 0:
                var mean = children[x+1][y].water_level * children[x+1][y].wet
                mean += children[x][y-1].water_level * children[x][y-1].wet
                mean += children[x-1][y].water_level * children[x-1][y].wet
                mean += children[x][y+1].water_level * children[x][y+1].wet
                mean /= wet_neighbours
                mean = clamp(mean, 0, 100)
                children[x][y].next_water_level = lerp(children[x][y].water_level, mean, 1)
            y += 1
        x += 1

    #update children
    x = 1
    while x < width:
        var y = 1
        while y < length:               
            children[x][y].water_level = children[x][y].next_water_level
            y += 1
        x += 1
...