Jump to content
Unity Insider Forum

Gibt es so was wie ein Wasser Script?


ichbin14

Recommended Posts

Das was macht?

Objekte darin Schwimmen lassen?

Wellen erzeugen?

Platscher, wenn man es berührt?

Dinge blau färben?

Schaden, wenn man zu lange drin bleibt?

Ein Objekt irgendwo langfließen lassen?

 

Wasser kann unheimlich viele Eigenschaften haben, Du musst schon genauer werden, was Du willst.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 10 months later...

Ich suche auch nach sowas ähnliches aber eher so wie Sascha schon sagte.

 

Schwimmen also Objekte wie Fässer ö.ä / Player etc.

 

Wellen wenn etwas rein fällt incl Permanente Wellen wie Dayligt Water etc.

 

Ps: Ich weis des ist ein Alter Post der sicherlich schon Erledigt ist,aber ich dachte mir, dafür nicht extra ein neues Thema zu eröffnen da die Frage quasi fast die gleiche ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ein enorm schwieriges Thema das sehr gute Programmierkenntnisse sowie gute Fähigkeiten in Physik (Wellenmodell) und Shaderprogrammierung vorraussetzt.

 

Wenn du endlich viele Wellen, die an festen Orten sind umsetzen willst ist es deutlich leichter, aber sobald etwas dynamisch sein soll, d.h. wenn z.B. Objekte die ins Wasser fallen Wellen schlagen wird es komplizierter. Ich hatte mal früher mit dem Gedanken gespielt ein kleines Ocean Toolkit für Unity zu entwickeln, dies liegt aber auf Eis, dennoch kann ich einige meiner Ideen gerne teilen.

 

LOD und Culling

Da Wasser, dass Wellen enthält, die nicht in Texturen gepackt sind einiges an Vertices benötigt, damit es ordentlich aussieht ist es empfehlenswert ein gutes LOD System zu implementieren. Hier kann im Prinzip genauso vorgegangen werden wie bei Terrain Rendering, denn wie ich später erläutern werde lässt sich ein dynamisches Wellensystem sehr gut mit Heightmaps realisieren, genauso wie Terrains. Mir persönlich hat der Algorithmus im Artikel "GPU Terrain Rendering" in "Game Programming Gems 6" sehr zugesagt. Es geht dort prinzipiell nur darum, dass das Terrain, bzw. das Wasser in Chunks unterteilt wird, die in unterschiedlichen Detailstufen gerendert werden. Zusätzlich zum LOD System war hier auch noch Culling der einzelnen Chunks eingebaut.

 

Dynamische Wellen

Ein gutes System sollte beliebig viele Wellen entgegennehmen und diese dann performant auf der Oberfläche simulieren. Meine Idee wäre es Emitter zu nutzen die im Unity Editor platziert oder zur Laufzeit des Spiels gespawnt werden. Man könnte hier nochmal zwischen unterschiedliche Emitterarten unterscheiden, ich werde mich jetzt aber mal auf PointEmitter beschränken. Dies sind dann also nur Punkte auf der Oberfläche an denen Wellen (Länge, Amplitude, Frequenz, etc.) gewpawnt werden, solange die Emitter aktiv sind.

 

Bevor das Wasser gerendert wird müssen nun jedes Frame die Wellendaten berechnet werden. Diese werden in eine Heightmap gerendert. Die Heightmap wird vorerst als RenderTarget behandelt was jedes Frame komplett gecleart wird, danach wird jeder Emitter durchgegangen und über einen Shader auf die Heightmap gezeichnet. Dies hat den Vorteil, dass alle Physikberechnungen auf der GPU stattfinden und das System daher enorm schnell ist. Ich könnte mir vorstellen, dass hier auch ohne Probleme 50 oder mehr Emitter verwendet werden könnten.

 

Zusätzlich könnte man noch der Heightmap unterschiedliche LOD Stufen geben, ähnlich wie Cascaded Shadow Maps, wie genau man das anstellen könnte habe ich mir aber noch nicht überlegt. Prinzipiell ist es aber nur wichtig, dass die Physikanimationen in der Nähe der Kamera hochaufgelöst ist, in der Ferne würde aufgrund des ohnehin verwendeten LOD Systems keine so hohe Heightmap Auflösung benötigt werden.

 

Rendern der Wasseroberfläche

Der spezielle Shader der Wasseroberfläche verwendet nun neben dem durch das LOD System übergebenen Parameter auch die Heightmap die im vorherigen Prozess gerendert wurde. Hier wird jedem Vertex, wie man aus dem Terrain Rendering kennt, eine Höhe anhand der Heightmap zugewiesen.

 

Zusätzlich kann man natürlich die üblichen optischen Zusätze hinzufügen, wie Specular Highlights, Normal Maps und Reflection, sowie Refraction.

 

"Unendliche" Wasseroberflächen

Nun hat man nicht immer begrenzte Wasseroberflächen wie kleine Seen oder Flüsse, sondern auch mal ganze Ozeane die sich quasi unendlich weit erstrecken sollen. Dieses System macht es eigentlich relativ einfach auch das zu erreichen, denn man kann den Wassermesh einfach mit der Kamera mitbewegen und dank des Heightmap basierten Physikmodells auch einfach den Center der Berechnungen für die Heightmap verschieben. Wenn man dann im Shader des Ozeans noch einige änderungen vornimmt (damit sich die Texturen nicht einfach mit der Kamera mitbewegen) dann ist das hier das meiste schon umgesetzt.

 

Physikalische Berechnung der Actors

Es gibt jetzt aber auch andere Objekte in der Szene die mit dem Wasser interagieren wollen, zum einen sollen sie Wellen auslösen, dies ist über das Erzeugen von neuen Emittern zur Laufzeit möglich, zum anderen sollen aber auch die Objekte von Wellen beeinflusst werden und auf der Wasseroberfläche treiben.

 

Hier könnte man eine Hand voll physikalischen Komponenten für die Objekte schreiben. Da man über die Heightmap jederzeit die Höhe an jeder beliebigen Stelle des Ozeans ermitteln kann, kann man einfach, je tiefer das Objekt ins Wasser kommt die Gegenkraft (ich bin kein Physikexperte auf dem Gebiet) berechnen, sodass das Objekt wieder nach oben treibt.

 

Außerdem könnte man die Heightmaps der vorherigen Frames speichern und eine "DeltaHeightmap" berechnen, welche jeweils die Tangente an jedem Punkt der Heightmap mittels der ddx und ddy Partielle Ableitungsanweisungen berechnet und sie mit der Tangente aus dem vorherigen Frame vergleicht. Die Abweichung wird dann in die DeltaHeightmap geschrieben. Wenn man das geschickt anstellt könnte man sicher irgendwie eine Kraft berechnen die durch Wellen entsteht, da dies ja in gewisser Weise mit der änderung der Normalen und Tangenten an der Oberfläche zusammenhängt.

 

Weitere Emitter

Bisher hatte ich nur Pointer Emitter erwähnt, aber mit dem Hinzufügen weitere Emitter kann man enorm interessante Effekte erzielen. Im Prinzip ist ein Emitter ja einfach nur ein kleines struct/class mit einigen Daten (im Falle des Point Emitters nur ein Vector3). Außerdem hat jeder Emitter eben auch einen Shader mit dem die physikalischen Berechnungen in eine Heightmap geschrieben werden.

 

Nun könnte man natürlich auch sehr einfach DIrectional Emitters erstellen, die einfach Wellen parallel in eine bestimmte Richtung aussenden. Aber mich hat vor allem eine Interaktion der Wellen mit dem Terrain faszieniert, und dies ist gar nicht mal so schwer zu realisieren. Denn auch das Terrain liegt als Heightmap vor, dementsprechend könnte man die Stellen Berechnen an denen das Terrain die Wasseroberfläche schneidet.

So könnte man Effekte wie das Wellen die sich immer in Richtung einer Inseln bewegen realisieren. Oder aber auch Wellen, die das Verhalten von Wasser von Flüssen vergleichsweise realistisch darstellt simulieren. Im Prinzip müssen sich die Wellen hier ja nur orthogonal zu den beiden Flussufern bewegen!

 

Fazit

Die Berechnung der Wellen in einer Heightmap bietet klar einige Vorteile, neben der dynamischen Anzahl und Position der Emitter können auch extrem viele Wellen verwendet werden und ganze von der simpleren Interaktion mit dem Terrain abgesehen.

 

Doch das System hat auch einige Einschränkungen, so kann man beispielsweise kein Wasser einen Berg herunterlaufen lassen oder über Objekte "schütten". Hier bietet sich ein DynamicFluid Modell an, wo das Wasser als Partikel behandelt wird, vor einigen Jahren hatte NVIDIA diesbezüglich eine interessante PhysX Demo veröffentlicht.

 

Meiner Meinung nach ist dies ein enorm faszinierendes Thema, doch genauso faszienierend wie es ist ist es auch kompliziert. Um ein solches System anständig zu implementieren bräuchte man selbst in einer recht einfach und intuitiv zu verwendeten Umgebung wie Unity mehrere Monate (Vollzeit!).

 

Vielleicht werde ich dieses Projekt irgendwann mal wieder aufnehmen, doch ich hoffe ich konnte dem einen oder anderen ein wenig weiter helfen ohne zu sehr abzuschrecken. Man kann ja auch einfach nur das implementieren, was man gerade braucht, je nachdem wie groß die Wasseroberfläche sein soll ist ein LOD System evtl. gar nicht so wichtig.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 1 year later...

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...