Проточная ГПУ вычисляет воду

15

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

Вы можете рассчитать количество воды, образованной во время дождя, используя формулу:
Q (CF/S) = c * I (in/hr) * A (acres)

Мне трудно выйти за рамки расчета «площади» даже первой области.

Обзор текущей реализации:

  1. Ландшафт представляет собой правильную сетку вершин с интервалом в 1 единицу.
  2. Карта высот содержит одно значение высоты R32 для каждой вершины
  3. В настоящее время я разрешаю поток только в 4 кардинальных направлениях (без диагоналей)
  4. Я использую Texture2D [int] как трафарет для вершин, которые я уже проанализировал

Текущий алгоритм:

  1. Когда инструмент ландшафта был активен и сейчас не ....
  2. Очистить «трафарет».
  3. Просканируйте всю местность для наименьшей высоты.
  4. Эта единственная точка является начальным входом в CS_Flood.
  5. CS_Flood делает проход по оси X.
  6. Каждая входная вершина проецируется в направлениях X и X + до 2048 раз.
  7. Поиск соседней вершины с координатой OOB указывает край местности в этом направлении. CurrentPoint добавляется в буфер BoundaryPoints, и цикл проецирования для этого направления прерывается. Это было легко и прекрасно работает каждый раз.
  8. Соседние вершины с высотой> = высота текущей вершины отмечены в трафарете и добавлены в буфер NextPass.
  9. Соседние вершины с высотой <высота текущей вершины указывает на пик гребня и завершает цикл проекции. Будущая итерация заливки может обтекать основание гребня, подниматься по его «задней» стороне и обнаруживать тот же гребень во второй раз.
  10. Для этой цели любые пиковые / ребристые точки, обнаруженные более одного раза, не будут BoundaryPoint.
  11. Любые пиковые / ребристые точки, обнаруженные ровно один раз, добавляются к BoundaryPoints, и цикл проецирования в этом направлении прерывается.
  12. CS_Flood делает проход по оси Z с тем же кодом, используя точки, сгенерированные проходом по оси X, в качестве входных данных.
  13. Прямо сейчас CS_Flood продолжает чередоваться между двумя направлениями бесконечно. В конце концов, я завершу весь цикл всякий раз, когда завершается CS_Flood и буфер NextPass пуст.

В идеале, в этой точке BoundaryPoints должны содержать каждую вершину, которая встречается на границе естественного дренажа. Капли воды, падающие в пределах границы, в конечном итоге текут к тому же низкому месту Капли воды приземляются за границей и уходят «куда-то еще».

Потом:

  1. Не очищая трафарет, повторно просмотрите местность на предмет самой низкой вершины без трафарета.
  2. Итерация CS_Flood.
  3. Повторяйте, пока трафарет не заполнится (или что-то подобное).

3D трудно воспринимать с этими цветами; это показывает линии контура на интегральных возвышениях:
(отверстие, окруженное бермой около края) край берм скважины

Существует около 10 уникальных способов стока через вершину; придание каждому из них уникального цвета выглядит следующим образом:
(видимые круглые следы инструмента, хорошо видны «гребни») введите описание изображения здесь

Это показывает каждую точку, сгенерированную CS_Flood, границей или иным образом, как POINTLIST: введите описание изображения здесь

Алгоритм почти всегда работает . Иногда это даже работает правильно. В других случаях алгоритм явно содержит правильную форму, но будет продолжать выводить точки бесконечно долго. Как видно на третьем скриншоте, иногда это запутывается. Должна быть другая ситуация / фактор, который я упустил из виду. Я был бы признателен за любую помощь в поиске моего контроля или предложений о более простых и / или более изящных способах решения проблемы.

недостающая точка

MissingPoint! может быть включен путем ленточной поддержки алгоритма для добавления каждого нового обнаруженного BoundaryPoint в буфер NextPass. Во время следующего прохода, 99% очков, сгенерированных этим лейкопластырем, будут тратить небольшое количество времени на GPU, определяя, что они никуда не денутся и ничего не делают. Во время первого прохода отправка LowestPoint вместе с другими точками NextPass также будет обрабатывать этот конкретный сценарий.

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

Джон
источник
То есть вы хотите просто вычислить, куда стекает вся вода на местности?
EvilTak
@ EvilTak, я думаю, что я выбрал хороший алгоритм, но я все еще получаю "странные вещи", которые у меня нет опыта, чтобы объяснить. Если вы хорошо разбираетесь в параллельных графических процессорах, ознакомьтесь: gamedev.stackexchange.com/questions/118556/…
Jon

Ответы:

1

Когда капля «пыталась» посетить вершину, трафарет был помечен с InterlockedExchangeиспользованием «исходного значения», чтобы определить, был ли он уже нанесен по трафарету (хотя я просто переписал его).

Лучший алгоритм, который я придумал, дал наводнению «блокнот» и единственное правило: «не течь вниз по склону» (высота равна или больше). Это устранило почти все сложные тесты. Хотя он обычно не течет по пикам / гребням, он течет вдоль них, потому что смежные вершины «плоские». Это иногда позволяет каплям пробираться мимо хребтов.

введите описание изображения здесь

Каждая из «слишком далеких» точек, таким образом, «течет» и будет течь «в» зону дренажа (останавливается на 1) или нет (останавливается на 0). «Ноты» отбрасываются, а исправленная блокнотная копия копируется в «финал». Если финал уже нанесен по трафарету, блокнот будет удален. (Будущее: эти столкновения должны все вместе представлять внешнюю границу текущей области дренажа.)

На 10FPS:

введите описание изображения здесь

«Ноты» отображаются красным цветом, как только большая область копируется в финал и становится зеленой, тогда алгоритм повторяется для оставшихся нестандартных областей.

Джон
источник