Ideen für die 2D-Wassersimulation

18

Ich suche nach Eingaben zur Simulation von Wasser in 2D gegen ein ziemlich großes (Call it) blockiertes / nicht blockiertes Array (von der Seite gesehen). Ich habe mir folgende Ideen ausgedacht:

Zellautomaten

Führen Sie eine massiv parralel Simulation auf der CPU unter Verwendung von Zell Automaten . Mit so einfachen Regeln wie:

  • Wenn eine Zelle nach unten offen ist, gehen Sie dorthin.
  • Überprüfen Sie die linke und rechte Zelle, wählen Sie eine zufällige aus den beiden und bewegen Sie sich dorthin.

Vorteile

  • Einfach zu implementieren.
  • Sinnvoll / deterministisch in einem Mehrspielersystem.

Nachteile

  • Wahrscheinlich sehr langsam.
  • Nicht überzeugend.

Fluiddynamik auf der GPU

Führen Sie eine grobe Näherung der Fluiddynamik auf der GPU anhand einer Textur wie der folgenden durch:

+------+-----+-----+-------+
|R     |G    |B    |A      |
+------+-----+-----+-------+
|vX    |vY   |NULL |Density|
+------+-----+-----+-------+

Vorteile

  • Wahrscheinlich sehr schnell.
  • Könnte durchaus überzeugend sein.
  • Ein weiterer Pixel-Shader könnte es direkt rendern.

Nachteile

  • Schwer zu implementieren.
  • Schwer zu optimieren.
  • Ich kann keine einzelne Textur der Größe meines Levels zuordnen.
    • Ich könnte die Gitterbereiche überlappen, aber dies würde die Komplexität weiter erhöhen.

Teilchen

Verwenden Sie Partikel, um das Wasser zu simulieren. Wenden Sie beim Rendern die additive Überblendung an und wenden Sie dann eine Multiplikationsfunktion auf den Alphakanal an, um dem Wasser scharfe Kanten zu verleihen.

Vorteile

  • Wird wahrscheinlich gut aussehen.
  • Einfach zu implementieren
  • Einfach zu rendern.
  • Sinnvoll in einem Multiplayer-System, obwohl die Übertragung eine Menge Bandbreite erfordern würde.

Nachteile

  • Interpartikeleffekte werden wahrscheinlich langsam sein (Nachbarschaftssuche).
  • Kann dazu führen, dass Wasser durch feste Räume "austritt" (weil der feste Raum klein ist, z. B. 1px).
  • Kann je nach Partikelgröße zu seltsamen Löchern im Wasser führen.
  • Beides könnte gemildert werden, indem Partikel näher aneinander driften als ihre tatsächliche Größe, dies würde jedoch Probleme mit der Leistung zwischen Partikeln und Partikeln / Landschaften verursachen.

Weitere Ideen?

Hinweis: Dies ist eine Annäherung, ich suche hier nicht das physikalisch korrekte Wasser - nur etwas, das "gut genug" ist (Bonuspunkte für schnell und schmutzig). Das Spiel ist im Mehrspielermodus, daher muss leider das gesamte Level kontinuierlich simuliert werden.

Jonathan Dickinson
quelle

Antworten:

12

Jedes Mal, wenn ich versucht habe, Wasser zu simulieren, habe ich einen Tiefpassfilter auf eine Textur angewendet, die den Wasserstand darstellt. Die Implementierung ist sehr einfach, schlägt jedoch immer dann fehl, wenn sich der Wasserstand massiv ändert und große Wellen entstehen können. Bei dieser Methode gibt es Orte, an denen das Wasser immer einen konstanten Füllstand aufweist, wie z. B. Flussenden. In diesen Fällen haben Sie genau die richtige Farbe für das jeweilige Pixel.

Vorteile:

  • einfach zu implementieren
  • realistische Ergebnisse bei ruhigem Wasser
  • schnelle Berechnung mit GPU
  • einfach zu definierende statische Wasserstände oder Wasserquellen

Nachteile:

  • Wellen können nicht simuliert werden

Für welliges Wasser verwende ich eine ähnliche Methode wie für Ihren Cell Automata-Algorithmus, aber mit einer kleinen Änderung, die es mir ermöglicht, Shader zu verwenden, um den nächsten Schritt der aktuellen Situation zu berechnen. Hier ist ein Sudo-Code Pixelfarbe:

foreach (pixel p) in oldTexture
{
    newtexture.pixels[p.x,p.y]    += p.color / 5;
    newtexture.pixels[p.x+1,p.y]  += p.color / 5;
    newtexture.pixels[p.x-1,p.y]  += p.color / 5;
    newtexture.pixels[p.x,p.y+1]  += p.color / 5;
    newtexture.pixels[p.x,p.y-1]  += p.color / 5;
}

Dieser Algorithmus verfügt über ähnliche Funktionen wie der vorherige, funktioniert jedoch in welligen Gewässern besser als in ruhigen. es ist Ihre Wahl, die auf dem Meer basiert, das Sie simulieren, um einen von ihnen zu verwenden.

Am Ende haben Sie eine Textur, die Ihnen den Wasserstand für jede Position angibt. Im nächsten Schritt müssen Sie auf irgendeine Weise Ergebnisse zeichnen. Der einfachste Weg ist, ein Netz basierend auf den Wasserstandsdaten zu generieren.

Ali1S232
quelle
Danke, das ist eine brillante Antwort. Ich lasse die Frage noch eine Weile offen. aber es scheint, als hätte ich ein Händchen dafür, hier eine Antwort auf Fragen zu geben :).
Jonathan Dickinson
Sie können diese Algorithmen auch mischen, um bessere Ergebnisse zu erzielen.
Ali1S232
Wie wäre es mit einem Screenshot?
Asche999
@ashes999 Ich habe keinen Screenshot, aber hier den gleichen Algorithmus implementiert! youtube.com/watch?v=avJPrL9UJ28
Ali1S232