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:
- Das Gelände ist ein regelmäßiges Gitter von Eckpunkten in Intervallen von 1 Einheit
- Eine Höhenkarte enthält einen R32-Höhenwert für jeden Scheitelpunkt
- Momentan erlaube ich nur den Fluss in die 4 Himmelsrichtungen (keine Diagonalen)
- Ich verwende eine Texture2D [int] als Schablone für Scheitelpunkte, die ich bereits analysiert habe
Aktueller Algorithmus:
- Wenn das Geländewerkzeug aktiv war und jetzt nicht ...
- Löschen Sie die "Schablone".
- Durchsuche das gesamte Gelände nach der niedrigsten Erhebung.
- Dieser einzelne Punkt ist die erste Eingabe für CS_Flood.
- CS_Flood lässt eine X-Achse passieren.
- Jeder Eingangsscheitelpunkt wird bis zu 2048-mal in X- und X + -Richtung projiziert.
- 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.
- Benachbarte Scheitelpunkte mit Höhen> = der Höhe des aktuellen Scheitelpunkts werden in der Schablone markiert und dem NextPass-Puffer hinzugefügt.
- 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.
- Zu diesem Zweck sind Spitzen- / Bergrückenpunkte, die mehr als einmal erkannt wurden, keine Grenzpunkte.
- Alle genau einmal erkannten Peak- / Ridge-Punkte werden an BoundaryPoints angehängt und die Projektionsschleife in dieser Richtung wird beendet.
- 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.
- 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:
- Scannen Sie das Terrain erneut nach dem niedrigsten, nicht schablonierten Scheitelpunkt, ohne die Schablone zu löschen.
- Iteriere CS_Flood.
- 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)
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)
Dies zeigt jeden Punkt, der durch CS_Flood, Boundary oder auf andere Weise erzeugt wird, als POINTLIST:
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.
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.