Fließende GPU berechnen Wasser


15

Ich bin Bauingenieur und führe regelmäßig hydraulische und hydrologische Analysen durch. Sie verkaufen Abschlüsse für solche Dinge, aber es ist wirklich keine Raketenwissenschaft. Ich hatte vor kurzem die Idee, den gesamten hydrologischen und hydraulischen Prozess für ein Gelände auf der GPU zu implementieren. Ich habe erst vor kurzem Compute-Shader gelernt, daher bin ich derzeit nicht in der Lage, parallele GPU-Workflows zu entwerfen.

Sie können die während eines Niederschlagsereignisses erzeugte Wassermenge mit der folgenden Formel berechnen:
Q (CF/S) = c * I (in/hr) * A (acres)

Ich habe Schwierigkeiten, über die Berechnung der "Anbaufläche" der ersten Fläche hinauszugehen.

Aktuelle Implementierungsübersicht:

  1. Das Gelände ist ein regelmäßiges Gitter von Eckpunkten in Intervallen von 1 Einheit
  2. Eine Höhenkarte enthält einen R32-Höhenwert für jeden Scheitelpunkt
  3. Momentan erlaube ich nur den Fluss in die 4 Himmelsrichtungen (keine Diagonalen)
  4. Ich verwende eine Texture2D [int] als Schablone für Scheitelpunkte, die ich bereits analysiert habe

Aktueller Algorithmus:

  1. Wenn das Geländewerkzeug aktiv war und jetzt nicht ...
  2. Löschen Sie die "Schablone".
  3. Durchsuche das gesamte Gelände nach der niedrigsten Erhebung.
  4. Dieser einzelne Punkt ist die erste Eingabe für CS_Flood.
  5. CS_Flood lässt eine X-Achse passieren.
  6. Jeder Eingangsscheitelpunkt wird bis zu 2048-mal in X- und X + -Richtung projiziert.
  7. Das Finden eines benachbarten Scheitelpunkts mit einer OOB-Koordinate zeigt die Geländekante in dieser Richtung an. CurrentPoint wird an den BoundaryPoints-Puffer angehängt und die Projektionsschleife für diese Richtung wird beendet. Das war einfach und funktioniert jedes Mal großartig.
  8. Benachbarte Scheitelpunkte mit Höhen> = der Höhe des aktuellen Scheitelpunkts werden in der Schablone markiert und dem NextPass-Puffer hinzugefügt.
  9. Benachbarte Scheitelpunkte mit Höhen <der Höhe des aktuellen Scheitelpunkts geben die Spitze eines Kamms an und beenden die Projektionsschleife. Eine zukünftige Iteration der Überflutungsfüllung könnte um die Basis des Kamms herum fließen, die "Rückseite" des Kamms hinauf und denselben Kamm ein zweites Mal entdecken.
  10. Zu diesem Zweck sind Spitzen- / Bergrückenpunkte, die mehr als einmal erkannt wurden, keine Grenzpunkte.
  11. Alle genau einmal erkannten Peak- / Ridge-Punkte werden an BoundaryPoints angehängt und die Projektionsschleife in dieser Richtung wird beendet.
  12. CS_Flood führt einen Z-Achsen-Durchlauf mit demselben Code aus, wobei die durch den X-Achsen-Durchlauf erzeugten Punkte als Eingabe verwendet werden.
  13. Momentan wechselt CS_Flood unbegrenzt zwischen den beiden Richtungen. Schließlich werde ich die Gesamtschleife beenden, wenn CS_Flood abgeschlossen ist und der NextPass-Puffer leer ist.

Idealerweise enthalten BoundaryPoints an diesem Punkt jeden Scheitelpunkt, der auf der natürlichen Drainageteilung auftritt. Wassertropfen, die innerhalb der Grenze landen, fließen schließlich zum gleichen Tiefpunkt. Wassertropfen, die außerhalb der Grenze landen, gehen "woanders hin".

Dann:

  1. Scannen Sie das Terrain erneut nach dem niedrigsten, nicht schablonierten Scheitelpunkt, ohne die Schablone zu löschen.
  2. Iteriere CS_Flood.
  3. Wiederholen, bis die Schablone voll ist (oder ähnliches).

3D ist mit diesen Farben schwer wahrzunehmen; Dies zeigt Konturlinien in integralen Höhen:
(ein Loch, umgeben von einer Berme in der Nähe des Randes) Randbermloch

Es gibt ungefähr 10 einzigartige Möglichkeiten, um über einen Scheitelpunkt hinweg zu entwässern. jeder eine einzigartige Farbe sieht aus wie geben:
(sichtbare kreisförmige Werkzeugspuren, „Rippen“ zeigen sich gut) Bildbeschreibung hier eingeben

Dies zeigt jeden Punkt, der durch CS_Flood, Boundary oder auf andere Weise erzeugt wird, als POINTLIST: Bildbeschreibung hier eingeben

Der Algorithmus funktioniert fast immer . Manchmal funktioniert es sogar richtig. In anderen Fällen weist der Algorithmus eindeutig die richtige Form auf, gibt jedoch weiterhin unbegrenzt viele Punkte aus. Wie im dritten Screenshot zu sehen ist, wird es manchmal verwirrt. Es muss eine andere Situation / einen anderen Faktor geben, den ich übersehen habe. Ich würde mich über jede Hilfe freuen, wenn ich mein Versehen finde oder Vorschläge für einfachere und / oder elegantere Wege, um das Problem anzugehen.

fehlender Punkt

MissingPoint! Sie können den Algorithmus bandunterstützen, um jeden neu erkannten BoundaryPoint zum NextPass-Puffer hinzuzufügen. Während des nächsten Durchgangs verschwenden 99% der mit diesem Pflaster erzielten Punkte eine geringe Menge an GPU-Zeit, um festzustellen, dass sie nirgendwo hingehen können und nichts tun. Während des ersten Durchgangs würde das Senden von LowestPoint zusammen mit den anderen NextPass-Punkten auch dieses spezielle Szenario behandeln.

Ich weiß, dass es plausibel ist, und wenn ich genug Zeit habe, kann ich es mit einer Band unterstützen, um das zu tun, was ich will. Ich würde es gerne besser, intelligenter und schneller machen, wenn möglich, und ich habe noch nicht genug Erfahrung, um es besser zu wissen.


Sie wollen also nur berechnen, wohin das Wasser im Gelände fließt?
EvilTak

@ EvilTak, ich glaube, ich habe mich auf einen guten Algorithmus festgelegt, aber ich bekomme immer noch "komische Sachen", die ich nicht erklären kann. Wenn Sie gut mit paralleler GPU umgehen können, lesen Sie bitte: gamedev.stackexchange.com/questions/118556/…
Jon

Antworten:


1

Wenn ein Tropfen versuchte, einen Scheitelpunkt zu "besuchen", wurde die Schablone mit InterlockedExchangedem "ursprünglichen Wert" markiert, um festzustellen, ob sie bereits schabloniert war (obwohl ich sie gerade überschrieb).

Der beste Algorithmus, den ich mir ausgedacht habe, gab der Flut einen "Notizblock" und eine einzige Regel: "Nicht bergab fließen" (Höhen gleich oder größer). Damit entfielen fast alle komplizierten Tests. Während es im Allgemeinen gut ist, nicht über Spitzen / Grate zu fließen, fließt es entlang dieser, weil die benachbarten Scheitelpunkte "flach" sind. Dadurch können sich Tropfen gelegentlich an Gratlinien vorbeischleichen.

Bildbeschreibung hier eingeben

Jeder der "zu weit" Punkte ist dann "geflossen" und fließt "in" den Entwässerungsbereich (stoppt bei 1) oder nicht (stoppt bei 0). Die "Nots" werden verworfen und der korrigierte Notizblock wird in das "Final" kopiert. Wenn das Finale bereits schabloniert ist, wird der Notizblock verworfen. (Zukunft: Diese Kollisionen sollten zusammen die äußere Grenze des aktuellen Entwässerungsgebiets darstellen.)

Bei 10 fps:

Bildbeschreibung hier eingeben

Die "Nots" werden rot angezeigt. Sobald der große Bereich in das Finale kopiert wurde und grün wird, wiederholt sich der Algorithmus für die verbleibenden nicht abgestimmten Bereiche.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.