Я маю досвід цивільного будівництва і регулярно виконую гідравлічний та гідрологічний аналіз. Вони продають градуси для такої речі, але це справді не ракетна наука. Нещодавно я зрозумів, щоб реалізувати весь гідрологічний та гідравлічний процес для місцевості на GPU. Я вивчив шейдери для обчислення лише нещодавно, тому в даний час я ліпший в галузі техніки, ніж проектування паралельних робочих процесів GPU.
Ви можете обчислити кількість води, що утворюється під час події опадів, за формулою:
Q (CF/S) = c * I (in/hr) * A (acres)
Мені важко перейти до вирахування «площі» навіть першої області.
Поточний огляд впровадження:
- Місцевість - це звичайна сітка вершин з інтервалом 1 одиниці
- Карта висоти містить одне значення висоти R32 для кожної вершини
- На даний момент я дозволяю протікати лише у 4-х кардинальних напрямках (без діагоналей)
- Я використовую Texture2D [int] як трафарет для вершин, які я вже проаналізував
Поточний алгоритм:
- Коли інструмент для місцевості був активним і зараз його немає…
- Очистіть «трафарет».
- Скануйте всю місцевість на найнижчу висоту.
- Цей єдиний пункт є початковим входом до CS_Flood.
- CS_Flood робить прохід по осі X.
- Кожна вершина введення проектується в обох напрямках X- та X + до 2048 разів.
- Знаходження сусідньої вершини з координатою OOB вказує на край місцевості в цьому напрямку. CurrentPoint додається до буфера BoundaryPoints і цикл проекції для цього напрямку припиняється. Це було легко і щоразу чудово працює.
- Суміжні вершини з висотами> = поточна висота вершини позначаються у трафареті та додаються до буфера NextPass.
- Суміжні вершини з висотами <поточна висота вершини вказують на вершину хребта і закінчують цикл проекції. Майбутня ітерація заливної заливки може протікати навколо основи хребта, вгору на "задній" стороні від нього та виявляти той же хребет вдруге.
- Будь-які точки вершини / хребта, виявлені не один раз , для цієї мети не будуть BoundaryPoint.
- Будь-які точки піку / хребта, виявлені рівно один раз, додаються до BoundaryPoints і цикл проекції в цьому напрямку припиняється.
- CS_Flood робить прохід по осі Z з тим же кодом, використовуючи точки, згенеровані проходом по осі X, як вхідні дані.
- Зараз CS_Flood продовжує чергуватися між двома напрямками нескінченно. Врешті-решт я припиняю загальний цикл, коли CS_Flood завершується, а буфер NextPass порожній.
В ідеалі, в цей момент BoundaryPoints містив би кожну вершину, яка виникає на природному відтоку дренажу. Краплі води, що висаджуються в межах кордону, врешті-решт стікають на ту саму низьку точку. Краплі води, що висаджуються біля кордону, йдуть «кудись інше».
Потім:
- Не очищаючи трафарет, повторно скануйте місцевість на найнижчу вершину, що не має трафіку.
- Ітерація CS_Flood.
- Повторюйте, поки трафарет не заповниться (або щось подібне).
3D важко сприймати за допомогою цих кольорів; це показує контурні лінії на цілих висотах:
(отвір, оточений бермою біля краю)
Існує близько 10 унікальних способів стікати через вершину; надання кожному унікального кольору виглядає так:
(видимі кругові позначки на інструменті, "хребти" добре відображаються)
Це показує кожну точку, згенеровану CS_Flood, межею чи іншим способом, як POINTLIST:
Алгоритм завжди майже працює . Іноді це навіть працює правильно. В іншому випадку алгоритм чітко міститься у правильній формі, але продовжує виводити точки нескінченно. Як видно з 3-го скріншота, іноді він плутається. Має бути інша ситуація / фактор, який я не помітив. Буду вдячний за будь-яку допомогу в пошуку моїх недоліків чи пропозицій щодо більш простих та / або більш елегантних способів атаки на проблему.
Відсутня точка! може бути включено, допомагаючи алгоритму, щоб додати кожну нову BoundaryPoint, виявлену до буфера NextPass. Під час наступного пропуску 99% балів, створених цією стрічковою допомогою, витратять невелику кількість часу на GPU, визначивши, що вони нікуди не можуть йти і нічого не роблять. Під час першого пропуску відправлення LowestPoint разом з іншими пунктами NextPass також оброблятиме цей конкретний сценарій.
Я знаю, що це правдоподібно, і, давши достатньо часу, я зможу надати допомогу йому достатньо, щоб зробити те, що я хочу. Я хотів би зробити це кращим, розумнішим, швидшим способом, якщо це можливо, і я не маю ще достатнього досвіду, щоб краще знати.