Тече GPU обчислює воду


15

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

Ви можете обчислити кількість води, що утворюється під час події опадів, за формулою:
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: введіть тут опис зображення

Алгоритм завжди майже працює . Іноді це навіть працює правильно. В іншому випадку алгоритм чітко міститься у правильній формі, але продовжує виводити точки нескінченно. Як видно з 3-го скріншота, іноді він плутається. Має бути інша ситуація / фактор, який я не помітив. Буду вдячний за будь-яку допомогу в пошуку моїх недоліків чи пропозицій щодо більш простих та / або більш елегантних способів атаки на проблему.

відсутність точки

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

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


Отже, ви хочете сказати, що ви просто хочете обчислити, куди стікає вся вода у місцевість?
EvilTak

@EvilTak, я думаю, що я налаштувався на хороший алгоритм, але я все ще отримую "дивні речі", які я не маю досвіду пояснювати. Якщо ви добре паралельні GPU'ing, будь ласка, перевірте: gamedev.stackexchange.com/questions/118556/…
Jon

Відповіді:


1

Коли крапля "спробувала" відвідати вершину, трафарет позначено за InterlockedExchangeдопомогою "оригінального значення", щоб визначити, чи він уже закреслений (хоча я просто його перезаписав).

Найкращий алгоритм, який я придумав, дав потопу «подряпину подряпин» і єдине правило: «не текти вниз по пагорбі» (висоти рівні або більше). Це усунуло майже всі складні тести. Хоча в цілому добре не протікати над вершинами / хребтами, проте він протікає по них, оскільки сусідні вершини "плоскі". Це час від часу дозволяє краплі проникнути повз лінії хребта.

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

Кожна з «надто далеких» точок є, таким чином, «перетікає» і перетікатиме «в» зону зливу (зупиняється на 1) чи ні (зупиняється на 0). "Nots" відкидаються, а виправлена ​​подряпина копіюється у "фінал". Якщо фінал вже зафіксований, то подряпини відкидаються. (Майбутнє: ці зіткнення повинні разом представляти зовнішню межу поточної зони водовідведення.)

При 10 кадрів в секунду:

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

"Nots" відображаються червоним кольором, як тільки велика площа скопіюється у фінал і стає зеленою, алгоритм повторюється для решти невстановлених областей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.