Programming lesson
Prozedurale Geländegenerierung mit Perlin Noise in Unity – Ein Leitfaden für Cs7632
Lerne, wie du mit Perlin Noise und einem hierarchischen Node-Graphen komplexe Höhenfeld-Terrain in Unity erzeugst. Schritt-für-Schritt-Anleitung für das Cs7632 Assignment 8 mit Fokus auf Biome und ScriptableObjects.
Einführung in die prozedurale Geländegenerierung mit Perlin Noise
Prozedurale Inhaltsgenerierung (PCG) ist ein mächtiges Werkzeug in der Spieleentwicklung, mit dem du endlos viele einzigartige Umgebungen erschaffen kannst, ohne jedes Detail manuell modellieren zu müssen. Eine der grundlegendsten Techniken ist die Verwendung von Perlin Noise, einem gradientenbasierten Rauschalgorithmus, der natürliche Formen wie Berge, Täler und Höhlen simuliert. In diesem Tutorial erfährst du, wie du mit Perlin Noise und einem hierarchischen Node-Graphen in Unity ein komplexes Höhenfeld-Terrain mit drei visuell unterscheidbaren Biomen erstellst – genau wie im Cs7632 Assignment 8 gefordert.
Stell dir vor, du entwickelst das nächste große Open-World-Spiel wie Genshin Impact oder Minecraft: Anstatt jede Landschaft von Hand zu bauen, legst du Regeln fest, die das Gelände automatisch generieren. Genau das lernst du hier. Und das Beste: Alles funktioniert im Unity Editor – kein Play-Modus nötig.
Was ist Perlin Noise und warum ist es perfekt für Gelände?
Perlin Noise wurde von Ken Perlin entwickelt, um natürliche Texturen zu erzeugen. Es erzeugt ein kontinuierliches, scheinbar zufälliges Muster, das aber bei verschiedenen Skalierungen (Frequenzen) wiederholbare Details liefert. Für Gelände bedeutet das: Du kannst mit niedrigen Frequenzen grobe Gebirgszüge formen und mit hohen Frequenzen feine Details wie Felsbrocken oder Sandwellen hinzufügen. Genau diese Multiskalen-Eigenschaft macht Perlin Noise zum idealen Ausgangspunkt für PCG.
Ein aktuelles Beispiel: In Palworld (2024) werden riesige Biome prozedural generiert – das wäre ohne Noise-Algorithmen undenkbar. Auch in der KI-gestützten Spieleentwicklung nutzen immer mehr Studios PCG, um Entwicklungszeit zu sparen und gleichzeitig die Spielwelt lebendig zu halten.
Aufbau des PCG-Graphen in Unity
Das bereitgestellte Unity-Projekt GameAI_PCG enthält eine Szene PCGTerrain. Öffne sie und wähle das GameObject mit der PCGTerrain-Komponente aus. Dies ist der Wurzelknoten deines Graphen. Von hier aus erstellst du Kindknoten, die jeweils eine Rauschschicht repräsentieren. Jeder Knoten hat folgende wichtige Parameter:
- Name: Benenne jeden Knoten eindeutig (z.B. „Mountains“, „SandDunes“, „Canyon“). Der Name im PCGTerrain-Component überschreibt den GameObject-Namen.
- X/Y/Z Offsets: Verschiebe den Rauschbereich, um unterschiedliche Ausschnitte zu erkunden – nützlich für Screenshots.
- MaxValue: Begrenzt die Amplitude des Rauschens (Höhe).
- PerlinScalar: Ändert die Frequenz – kleine Werte erzeugen sanfte Hügel, große Werte viele Details.
- GenNoiseType: Wähle PerlinNoise (Standard), PerlinNoiseWithMappingCurve (eigene Kurve) oder None (kein Rauschen, Default-Wert 1.0).
- ProcessParentType: Bestimmt, wie das Elternrauschen verarbeitet wird: Passthrough, Inverted, ProcessParentCurve oder TrapezoidFunction. Letzteres ist ideal für Biome-Segmentierung.
- CombineType: Legt fest, wie der aktuelle Knotenwert mit dem Elternwert kombiniert wird: Add, Subtract, Multiply, NormalizeFromParentToTop, Complement oder Mute.
Die Schaltflächen am unteren Rand der Komponente sind essenziell: Add Child PCG Terrain Node fügt einen Kindknoten hinzu, Delete this Node (and children) löscht den gesamten Teilbaum (Vorsicht – keine Rückgängig-Funktion!), und Save to ScriptableObject speichert den Graphen als PCGTerrainData.asset. Vergiss nicht, nach dem Speichern auch die Unity-Szene zu speichern, sonst gehen Änderungen bei einem Absturz verloren.
Biome-Segmentierung mit der Trapezoid-Funktion
Eine der elegantesten Methoden, um drei unterschiedliche Biome zu erzeugen, ist die TrapezoidFunction. Stell dir vor, das Elternrauschen ist ein Höhenprofil von 0 bis 1. Mit der Trapezoid-Funktion definierst du einen „Bandpass“: Alles unterhalb eines unteren Schwellwerts wird auf 0 gesetzt, alles oberhalb eines oberen Schwellwerts ebenfalls, und dazwischen entsteht ein Plateau (oder ein sanfter Übergang).
Konkret: Du erstellst einen Wurzelknoten, der grobes Rauschen (niedrige Frequenz) erzeugt. Drei Kindknoten wenden jeweils eine Trapezoid-Funktion mit unterschiedlichen Bandpass-Parametern an. Zum Beispiel:
- Kind 1 (Berge): Bandpass von 0,6 bis 0,9 – nur hohe Werte des Elternrauschens werden durchgelassen.
- Kind 2 (Sanddünen): Bandpass von 0,2 bis 0,5 – mittlere Höhen.
- Kind 3 (Canyon): Bandpass von 0,0 bis 0,2 – tiefe Lagen, die dann invertiert oder mit einem zweiten Rauschen überlagert werden.
Jeder Kindknoten kann dann sein eigenes Rauschen (mit höherer Frequenz) hinzufügen, um Details wie Felsformationen oder Dünenmuster zu erzeugen. Die CombineType sollte meist Add oder Multiply sein. Mit NormalizeFromParentToTop verhinderst du, dass die Höhe den Maximalwert (1.0) überschreitet.
Dieser Ansatz erinnert an die Biome-Generierung in Valheim oder No Man’s Sky – Spiele, die mit prozeduralen Algorithmen riesige Welten erschaffen. Auch in aktuellen KI-Trends wie generativen Umgebungen für Simulationen wird dieses Prinzip genutzt.
Schritt-für-Schritt-Anleitung zum Erstellen deines Terrains
- Wurzelknoten konfigurieren: Setze GenNoiseType auf PerlinNoise, PerlinScalar auf 0.01 (für grobe Kontinente), MaxValue auf 1.0. Benenne ihn „BaseTerrain“.
- Ersten Biome-Knoten hinzufügen: Klicke auf Add Child PCG Terrain Node. Nenne ihn „Mountains“. Setze ProcessParentType auf TrapezoidFunction und konfiguriere die vier Variablen: StartFadeIn = 0.6, BandStart = 0.7, BandEnd = 0.9, EndFadeOut = 1.0. Wähle CombineType = Add. Füge ein zweites Rauschen mit PerlinScalar = 0.05 und MaxValue = 0.3 hinzu, um Details zu erzeugen.
- Zweiten Biome-Knoten hinzufügen: Erstelle einen weiteren Kindknoten „SandDunes“. Trapezoid-Parameter: 0.2, 0.3, 0.5, 0.6. CombineType = Add. Eigenes Rauschen mit PerlinScalar = 0.1, MaxValue = 0.2.
- Dritten Biome-Knoten hinzufügen: „Canyon“. Trapezoid: 0.0, 0.0, 0.2, 0.3. CombineType = Subtract (um Täler auszuheben) oder Complement. Eigenes Rauschen mit PerlinScalar = 0.08, MaxValue = 0.15.
- Feinjustierung: Spiele mit den Offsets und Skalaren, bis die Biome klar erkennbar sind. Nutze die Validate-Schaltfläche, um sicherzustellen, dass der Graph konsistent ist.
- Speichern: Klicke auf Save to ScriptableObject. Benenne die Datei als PCGTerrainData.asset. Speichere dann die Szene über das Dateimenü.
Tipps für perfekte Screenshots und häufige Fehler
Um überzeugende Screenshots zu machen, bewege dich mit WASD und der Maus (linke/rechte Maustaste für Höhenänderung) durch die Szene. Wähle Blickwinkel, die die Übergänge zwischen den Biomen zeigen. Vermeide es, den Graphen zu komplex zu machen – drei bis fünf Knoten reichen völlig aus. Typische Fehler sind:
- Vergessen, den Knotennamen zu ändern: Der Name im PCGTerrain-Component ist entscheidend.
- Zu viele Knoten: Das kann die Performance im Editor drastisch verschlechtern. Reduziere die Terrain-Auflösung in den Projekteinstellungen, falls nötig.
- Unsaubere Trapezoid-Werte: Stelle sicher, dass die vier Werte in aufsteigender Reihenfolge sind (z.B. 0.2, 0.3, 0.5, 0.6). Sonst entstehen unerwartete Lücken.
- Nicht gespeichert: Nach dem Speichern des ScriptableObjects auch die Szene speichern – sonst sind die Änderungen bei einem Crash verloren.
Erweiterte Ideen: Mapping-Kurven und Crossfading
Für noch weichere Übergänge zwischen Biomen kannst du anstelle der Trapezoid-Funktion die ProcessParentCurve verwenden. Das ist rechenintensiver, erlaubt aber individuell geformte Übergänge. Oder du kombinierst mehrere Rauschschichten mit unterschiedlichen Frequenzen, um realistischere Geländeformen zu erhalten – ähnlich wie bei der fraktalen Rauschüberlagerung (FBM).
Ein aktueller Trend in der Spieleentwicklung ist der Einsatz von maschinellem Lernen zur Optimierung von PCG-Parametern. Du könntest zum Beispiel mit einem einfachen genetischen Algorithmus die optimalen PerlinScalar- und MaxValue-Werte für deine Biome finden. Das wäre eine spannende Erweiterung über das Assignment hinaus.
Fazit
Mit Perlin Noise und einem hierarchischen Node-Graphen kannst du in kurzer Zeit beeindruckende Terrains erstellen. Die Technik ist nicht nur für Spiele relevant, sondern auch für Simulationen, VR-Umgebungen und sogar für KI-Trainingsdaten. Das Cs7632 Assignment 8 gibt dir die perfekte Gelegenheit, diese Fertigkeiten praktisch zu üben. Denk daran: Deine PCGTerrainData.asset, die readme.txt und vier Screenshots sind die Abgabe. Teile deine Ergebnisse auf Piazza – du wirst sehen, wie vielfältig die Terrains aussehen können.
Prozedurale Generierung ist ein mächtiges Werkzeug, das dir unendliche kreative Freiheit gibt. Mit den hier gelernten Grundlagen kannst du dich an größere Projekte wagen – vielleicht an eine komplette Spielwelt mit mehreren Inseln oder einem prozeduralen Dungeon. Viel Erfolg!