Für mein postapokalyptisches
Frameshift- Spiel
musste ich eine sehr große offene Welt mit verschiedenen Städten füllen. Unser Team hat nur 3 Leute, also habe ich natürlich die prozedurale Kraft von Houdini genutzt!
Früher, als ich Houdini nicht kannte, schrieb ich in C # meine eigenen Tools für die prozedurale Netzgenerierung für Unity. Das Hinzufügen neuer Funktionen war ein sehr langer Prozess, und als ich einmal hörte, dass Houdini für solche Aufgaben ausgelegt ist, wechselte ich sofort zu Houdini. Ich habe mit verschiedenen Arten der Erzeugung von Städten und Straßen experimentiert und in diesem Artikel werde ich kurz auf die Technik eingehen, die ich letztendlich für das Spiel verwendet habe.
Zuerst habe ich ein Tool zum Generieren eines Straßennetzes erstellt, das in der Stadt verwendet werden kann. Meine Entscheidung basiert auf
den hier vorgestellten Konzepten sowie auf dem als Referenz verwendeten Artikel. Es wird viel über Tensorfelder und Eigenvektoren geredet, und alles ist sehr technisch geschrieben, aber auf den Punkt gebracht kann es folgendermaßen erklärt werden: Für meinen Fall (Erzeugen eines Straßennetzes auf einem Relief) musste ich Konturentlastungslinien sowie dazu senkrechte Linien erzeugen.
Ich habe mit dem Relief begonnen und dank ein wenig Hilfe aus dem Houdini Gubbins-Beispiel Vektoren an jedem Punkt des Reliefs erzeugt, der auf den Pfad gerichtet ist, und Verlaufslinien mit VEX:
Gelbe Vektoren zeigen Konturlinien.
Dann müssen wir ein Raster von Stadtstraßen erstellen und deren Vektoren mit Vektoren mischen, die die natürlichen Kurven des Reliefs wiederholen. So werden wir ein Gebiet schaffen, das einem Raster von Stadtstraßen ähnelt und sich gut mit dem Relief verbindet. Hier platzieren wir das Raster auf dem Relief und dann die Polyframe-Funktion, sodass die Normalen entlang der Rasterlinien ausgerichtet werden, fügen einen Abfall für eine gleichmäßige Überblendung hinzu und legen schließlich einen neuen Pfadvektor fest, der eine Mischung aus zwei Vektoren ist:
In der Abbildung oben sehen Sie, dass die Konturlinien innerhalb der Ränder des Rechtecks eher einem Raster ähneln. Ich führe auch einen ähnlichen Prozess durch, um dem Spiel den Einfluss von manuell erstellten Straßen hinzuzufügen. In Unity HDA habe ich einen Schieberegler eingeführt, mit dem der Einfluss geändert werden kann, um natürlichere oder „quadratischere“ Straßen innerhalb der Stadtgrenzen zu erstellen.
Als nächstes werde ich die Vektorfelder in VDB konvertieren, damit Sie daraus Muster erstellen können, um vorgefertigte Straßen zu erstellen. Mit SOP Volume Tracking erhalten Sie eine schöne Visualisierung:
Es fängt schon an, wie ein Straßenraster auszusehen! Sie sind zu nahe beieinander, aber im Allgemeinen gibt es bereits Formen. Dann führen wir viele Stichprobenvorgänge aus VDB-Geschwindigkeiten und vielen ärgerlichen Vorgängen durch, um vorgefertigte Straßenlinien zu erstellen. Der Vex-Code ordnet die Straßen im Wesentlichen in der richtigen Entfernung an und beendet sie, wenn sie zu nahe an anderen Straßen oder zu lang sind:
Anschließend führen wir eine Nachbearbeitung durch, um alles zu glätten, kleine Teile zu entfernen, die Sackgassen zu verlängern, um realistische Kreuzungen zu erstellen, und Straßen auf dem Gelände zu verlegen. Das Endergebnis sieht so aus:
Es gibt immer noch ein paar unrealistische Teile, aber eine kleine manuelle Bereinigung in Unity ist akzeptabel, wenn man bedenkt, wie viel Zeit wir dabei gespart haben.
Wir haben also prozedural ein Stadtstraßennetz generiert, aber das Ergebnis waren nur ein paar Kurven in Houdini. Jetzt zeige ich Ihnen, wie Sie für jede dieser Kurven eine Straßengeometrie erstellen, um Netze zu erstellen, die Sie in Unity verwenden können. Hier sind unsere vorherigen Ergebnisse, die auf Unity portiert wurden:
Zuerst müssen Sie mitteilen, wie die Datenübertragung zwischen Houdini und Unity durchgeführt wird. Bei Straßen schreibe ich eine Reihe von Punkten, die Breite der Straße und die voreingestellte Straßenoberfläche in die JSON-Datei. In Unity habe ich Editor-Tools zum manuellen Bearbeiten von Straßen mithilfe von Bezier-Kurven erstellt:
In Suchmaschinen finden Sie zahlreiche Lernprogramme zum Erstellen eines Bezier-Kurveneditors in Unity. Um Daten zurück nach Houdini zu übertragen, benutze ich den Python-Knoten, um die JSON-Datei zu lesen:
Hier sehen Sie das Ergebnis der Erstellung eines städtischen Straßennetzwerks, das oben beschrieben wurde. Dieses Mal wird es jedoch aus der JSON-Datei gelesen, da es jetzt von Unity mit manuellen Änderungen abgerufen wird.
Ich importiere auch ein Relief von Unity und lese seine Rohdaten. Wahrscheinlich kann es heute nativ mit HDA durchgeführt werden, da die Houdini-Engine die Unterstützung für Unity-Terrain verbessert hat, aber als ich diese Arbeit erledigte, war es immer noch nicht so gut.
Dann erstellen wir die Schnittpunkte. Die Hauptarbeit wird hier von der Kreuzungsstich-SOP geleistet, aber ich habe auch VEX verwendet, um die Straßen ein wenig zu verlängern, falls sie sich nicht vollständig kreuzten, und die kurzen Enden entfernt, damit die T-Kreuzungen korrekt erstellt wurden.
Als nächstes erstelle ich eine Gruppe von Kreuzungen mit Hilfe des Abfalls vom Kreuzungspunkt, wobei der Abstand der Schwächung gleich dem breitesten am Kreuzungspunkt der Straße ist. Dann erweitere ich diese Gruppe von Kanten in Fällen, in denen der Winkel zwischen zwei Straßen weniger als 45 Grad beträgt, so dass zwischen den beiden Enden der Kreuzung genügend Platz vorhanden ist, um ein Netz mit der gewünschten Breite zu erstellen:
Die Berechnungen im VEX-Knoten ermitteln die Hypotenuse eines rechtwinkligen Dreiecks (wir können annehmen, dass jeder einzelne Teil der Schnittmenge aus zwei rechtwinkligen Dreiecken besteht):
Da wir wissen, wie breit die Straßen der Kreuzungsgruppe sein sollten (in der Abbildung oben als A angegeben) und den Winkel a kennen, können wir C berechnen, um den Abstand zu ermitteln, um den wir die Kreuzungsgruppe erweitern müssen, um sie durch die gewünschte Breite zu teilen.
Dann erstellen wir Gruppen von Brücken, die Straßenabschnitte markieren, die sich über einer bestimmten Entfernung über dem Boden befinden. Dies geschieht mit Ray SOP, wobei die Option "Punktkreuzungsabstand" aktiviert und "Punkte transformieren" deaktiviert ist. Um vorgefertigte Kurven für die Abschlussgeometrie zu erstellen, verwenden wir Polycut, um die Kreuzungs- und Brückengruppen so zu schneiden, dass nur noch normale Straßen übrig bleiben.
Und jetzt fangen wir endlich an, echte Maschen zu schaffen. Das Subnetz, das die Schnittmengen erstellt, ist eine modifizierte Version des Lernprogramms zum
Lösen von Schnittmengen . Das Subnetz, das die Geometrie der Straße erstellt, schließt auch die Linie und erstellt UV. Es gibt ein weiteres
großartiges Tutorial, das von HoudiniSimon erstellt wurde. Hier erfahren Sie, wie Sie UV-Strahlen erzeugen, um eine geschlossene Kurve zu biegen. Der erste Teil des Tutorials kann jedoch auf offene Kurven angewendet werden.
Dann habe ich nur einige Gruppen erstellt, um die Materialien für die Verwendung des roadPreset-Attributs anzuwenden, das aus meinen Kurven in Unity übernommen wurde.
Als nächstes erstellen wir die Geometrie der Brücken. Das unten gezeigte Netzwerk durchläuft iterativ alle zuvor erstellten Brückengruppen und fügt je nach Höhe über dem Boden, Länge und Tortuosität entweder eine Bulk- oder eine Bogenbrücke ein. In einem separaten Lernprogramm wird das Erstellen einer Bogenbrücke beschrieben. Bei der Massenbrücke wird die zuvor erstellte Brückengeometrie entlang der Brückenkurve mithilfe der SOP "Hervorragende Sweep-Geometrie" mit Start- und Endgruppen geschlossen.
Ergebnis:
Diese Brückennetze bestehen aus manuell modellierten Start- / End- / Mittelabschnitten, die verformbar sind und entlang einer Kurve unter Verwendung der Wobbelgeometrie SOP von Gamedev dupliziert werden. So sehen die manuell erstellten Geometrien und Gruppen aus:
Die zentrale Gruppe ist hervorgehoben, und die Enden befinden sich in den Gruppen bridgeStart und bridgeEnd, die vom Geometrieverschlussknoten verwendet werden.
Wir vervollständigen die Brücke, indem wir sie ein wenig extrudieren, um einen Straßendamm zu schaffen, auf den Kiestextur aufgetragen wird. Für Kreuzungen bestimmter Straßentypen werden auch mehrere boolesche Variablen festgelegt. Wenn sich beispielsweise eine unbefestigte Straße mit einer Autobahn kreuzt, wird sie abgeschnitten.
Am Ende speichern wir die gesamte Geometrie für die Verwendung in Unity und in zusätzlichen Houdini-Werkzeugen. Wir teilen die Straßennetze in kleinere Fragmente auf und exportieren sie als FBX. Außerdem speichern wir die Daten in .bgeo-Dateien, damit sie später verwendet werden können.
In der Einheit:
Ich hoffe, Ihnen hat diese kurze Beschreibung unseres Erstellungsprozesses der Houdini-Straßengeometrie gefallen. Im nächsten Beitrag werde ich darüber sprechen, Straßenmarkierungen zu erstellen und das Gelände so auszurichten, dass es besser mit den Straßen übereinstimmt.