Eine offene Welt im Browser bauen, Teil 27: Eine Insel aus Rauschen und Boden, der wie echter Boden aussieht
Von Oleg Sidorkin, CTO und Mitgründer von Cinevva
Neu hier? Nutze den Serienleitfaden. Er erklärt, was ein Spike ist, und verlinkt alle Teile.
Teil 26 brachte Wasser in die Welt. Dieser Teil baut das Land darunter, in zwei Phasen, die widerspiegeln, wie ein realer Ort entsteht. Spike 54 ist das Gelände selbst: nicht von Hand modelliert, sondern aus Rauschen gewachsen und anschließend so lange verwittert, bis es die Abflusswege und die Küstenlinie eines Ortes besitzt, über den tatsächlich Wasser geflossen ist. Spike 55 ist die Oberfläche dieses Geländes: Er löst das Problem, an dem fast jeder prozedurale Boden scheitert, nämlich dass eine gekachelte Textur auch gekachelt aussieht. Zusammen beantworten sie eine Frage: Können Kreative eine plausible Insel und einen Boden erzeugen, der als echter Boden wahrgenommen wird, ohne dass ein Künstler eines von beidem anfasst? Die Antwort lautet ja, wenn man die richtigen Verfahren übernimmt.
Eine Küstenlinie, die Rauschen allein nicht erzeugen kann
Spike 54 in einem neuen Tab öffnen ↗ · Quellcode ansehen
Die Höhenkarte folgt den Verfahren von Red Blob Games, einer Folge kleiner Transformationen, von denen jede einen bestimmten Fehler in rohem Rauschen behebt. Fraktale Brownsche Bewegung summiert mehrere Oktaven Perlin-Rauschen, sodass das Gelände sowohl breite Hügel als auch feine Details besitzt. Einfaches FBM wirkt jedoch weich und am Raster ausgerichtet, daher wird der Abtastpunkt zunächst per Domain Warping verzerrt: Jede Koordinate wird durch ein weiteres Rauschfeld verschoben,
Damit erhält man eine Form, aber eben eine Rauschform. Sie hat keine Flüsse, keine vom Wasser eingeschnittenen Täler und keine Sedimentfächer, weil nie etwas über sie hinweggeflossen ist. Die Lösung ist hydraulische Erosion, portiert aus Sebastian Lagues MIT-lizenzierter Implementierung. Tausende Wassertropfen entstehen an zufälligen Positionen und rollen bergab. Jeder besitzt eine Trägheit, damit er keine scharfen rechtwinkligen Kurven nimmt, nimmt beim Beschleunigen Sediment auf und lagert es beim Abbremsen oder in Senken wieder ab. Ein vorberechneter kreisförmiger Pinsel verteilt jedes Erosionsereignis über einen kleinen Radius, sodass eine glatte Furche statt eines einen Pixel breiten Kratzers entsteht. Durch Verdunstung verschwindet der Tropfen im Laufe seiner Lebensdauer. Lässt man genügend Tropfen laufen, entwickelt das Gelände etwas, das Rauschen nicht vortäuschen kann: zusammenlaufende Abflussnetze, flussabwärts breiter werdende Täler und Ebenen, auf denen sich Sediment abgelagert hat.
Erosion auf der GPU und Flüsse, die wissen, wo sie verlaufen
Die CPU-Erosion ist korrekt, aber langsam. Deshalb portiert der Spike sie auch in einen WebGPU-Compute-Shader. Interessant daran ist, zu welchen Entscheidungen einen GPU-Atomics zwingen. Höhen werden als Festkommawerte vom Typ i32 mit einem Skalierungsfaktor von einer Million gespeichert, weil WGSL keine atomare Addition für Gleitkommazahlen unterstützt. Die einzige Möglichkeit, wie Tausende Tropfen parallel und ohne Race Conditions Sediment in derselben Zelle ablagern und daraus entfernen können, sind atomicAdd und atomicSub auf Ganzzahlen. Durch die Festkomma-Konvertierung kann eine Zelle bei starker gleichzeitiger Abtragung gelegentlich leicht negativ werden. Das ist harmlos und wird beim Zurücklesen begrenzt. Die CPU-Version berechnet für jede Zelle vorab eine Pinseltabelle. Bei einem Raster von
Zwei weitere Durchläufe verwandeln das verwitterte Gelände in eine gut lesbare Karte. Für die Entwässerung kommt die D8-Flussakkumulationsmethode von Red Blob zum Einsatz: Auf jede Zelle fällt eine Einheit Regen, alle Zellen werden absteigend nach Höhe sortiert und jede Zelle gibt ihr angesammeltes Wasser an ihren einzigen niedrigsten Nachbarn weiter. So sammelt sich das Wasser entlang der natürlichen Täler, und jede Zelle, deren Akkumulation einen Schwellenwert überschreitet, wird als Fluss markiert. Das Problem ist, dass eine erodierte Höhenkarte Senken besitzt, also lokale Vertiefungen ohne tiefer gelegenen Ausweg. Wasser, das in eine solche Senke fließt, bleibt einfach stehen und unterbricht die Akkumulation. Bevor die Entwässerung berechnet wird, hebt das Planchon-Darboux-Verfahren zur Senkenauffüllung deshalb jede Senke knapp über ihren niedrigsten Nachbarn an,
Die Kachel, die sich unaufhörlich wiederholt
Spike 55 in einem neuen Tab öffnen ↗ · Quellcode ansehen
Ein Gelände braucht ein Material, das Kilometer mit einer nur wenige Meter großen Textur bedeckt. Sobald man eine Kachel so skaliert, dass sie den Boden überzieht, erkennt das Auge sofort die Wiederholung. Spike 55 ist ein A/B-Vergleich von vier Sampling-Modi auf derselben Geometrie und mit derselben Beleuchtung. Die einzige Variable ist also, wie die Textur gelesen wird. Die Ausgangsbasis ist plain: ein einziges Sample an der skalierten UV-Koordinate, das sich offensichtlich alle paar Meter wiederholt und nur als Referenz dient, die es zu schlagen gilt. Die kostenlosen PBR-Layer stammen von Poly Haven und werden über dessen CDN geladen: Diffuse-Textur, gepackte ARM-Map (Ambient Occlusion, Rauheit, Metallizität) und eine GL-Normal-Map. Alles ist CC0-lizenziert und wird mit Anisotropie 8 und Mipmaps geladen.
Die drei interessanten Modi greifen die Wiederholung auf unterschiedliche Weise an. Der Modus hex-linear verwendet das Dreiecksraster von Heitz und Neyret: Über die Oberfläche wird ein schiefes Dreiecksgitter gelegt. Jedes Fragment befindet sich in einem Dreieck, dessen drei Eckpunkte jeweils ein zufällig versetztes Sample verwenden. Diese werden anhand baryzentrischer Gewichte überblendet, sodass benachbarte Bereiche unterschiedliche Teile der Textur abtasten und sich die großflächige Kachelung auflöst. Eine einfache lineare Überblendung von drei Samples mittelt ihre Farben an den Dreiecksrändern jedoch, wodurch ein sichtbares Dreiecksmuster entsteht — genau das Artefakt, auf das Spike 48 gestoßen ist. Der Modus hex-vp nutzt die veröffentlichte Korrektur aus demselben Paper von 2018: Nach der baryzentrischen Summe wird die mittlere Texturfarbe abgezogen, das Ergebnis mit der inversen Quadratwurzel der Summe der quadrierten Gewichte skaliert, damit die Varianz konstant bleibt, und anschließend der Mittelwert wieder addiert. Dadurch bleibt der Kontrast über die Überblendung hinweg stabil und die Dreiecke verschwinden. Deshalb liest das Material jede geladene Textur zu Beginn einmal mit einer Größe von 1 mal 1 zurück, um ihre mittlere Farbe zu schätzen. Der vierte Modus, iq-untiled, ist Technik 3 aus Inigo Quilez’ „Texture Repetition“: Zwei versetzte Samples werden anhand eines niederfrequenten Variationsmusters überblendet. Es sind nur zwei statt drei Samples nötig, und eine Dreiecksstruktur gibt es von vornherein nicht — eine kostengünstige Lösung, die sich gut behauptet.
Über jedem Modus kann optional eine triplanare Projektion liegen. Dadurch kann dasselbe Material eine Klippe ohne Verzerrung überziehen. Statt einer einzelnen UV-Koordinate tastet der Shader drei Projektionen entlang der Weltachsen ab: Zur X-Achse gerichtete Oberflächen lesen die YZ-Ebene, Y liest ZX und Z liest XY. Sie werden anhand von abs(normalWorld) überblendet, potenziert mit einem Schärfungswert zwischen vier und acht, damit eine Neigung von 45 Grad nicht alle drei Projektionen zu einem verschwommenen Gemisch überlagert. Der Vergleich macht die Abwägung deutlich: Die varianzerhaltende Hex-Überblendung liefert die beste Qualität, während Quilez’ Variante mit zwei Samples die leistungsbewusste Wahl ist. Beide schlagen die einfache Variante so deutlich, dass kein Kreativer jemals die einfache Kachel veröffentlichen sollte.
In diesem Kapitel erwähnte Technologien
Höhenkartenerzeugung aus kombinierten Verfahren. Die Verfahren von Red Blob Games setzen rohes Rauschen zu Gelände zusammen: Domain-Warped-FBM (
Hydraulische Erosion auf CPU und GPU. Sebastian Lagues Tropfenmodell mit Trägheit, Transportkapazität, einem vorberechneten kreisförmigen Ablagerungspinsel und Verdunstung gräbt echte Abflusswege, die Rauschen nicht vortäuschen kann. Die WebGPU-Compute-Portierung speichert Höhen als Festkommawerte vom Typ i32 mit einem Skalierungsfaktor von einer Million, damit Tropfen parallel atomicAdd/atomicSub auf derselben Zelle ausführen können. Sie berechnet den Pinsel jedes Tropfens bei Bedarf neu, um bei
D8-Entwässerung mit Senkenauffüllung. Die D8-Flussakkumulation von Red Blob lässt eine Einheit Regen auf jede Zelle fallen, sortiert die Zellen nach absteigender Höhe und gibt das Wasser an den jeweils niedrigsten Nachbarn weiter. Oberhalb eines Schwellenwerts werden Zellen als Flüsse markiert. Zuvor hebt die Planchon-Darboux-Senkenauffüllung jede lokale Vertiefung auf
Vier Methoden gegen Texturkachelung. Auf identischer Geometrie und bei identischer Beleuchtung: plain (ein Sample, offensichtlich gekachelt), hex-linear (Heitz-Neyret-Dreiecksraster, bei dem die lineare Überblendung ein Dreiecksmuster hinterlässt), hex-vp (die varianzerhaltende Korrektur aus EGSR 2018 §3.3, die den Mittelwert abzieht, mit der inversen Quadratwurzel der quadrierten Gewichte skaliert und den Mittelwert wieder addiert, wofür jede Textur einmal mit 1×1 Pixeln zurückgelesen werden muss) und iq-untiled (Inigo Quilez’ Technik 3 mit zwei Samples). Die triplanare Projektion tastet drei Ebenen entlang der Weltachsen ab und überblendet sie anhand von abs(normalWorld) hoch 4 bis 8, damit Texturen an Klippen nicht gestreckt werden. Die varianzerhaltende Variante gewinnt bei der Qualität, die Variante mit zwei Samples bei den Kosten. Siehe Geländematerialien.
Teil 27 von 29. Zurück: Teil 26 – Drei Methoden, Wasser zu erzeugen Weiter: Teil 28 – Gras bis zum Horizont und Boden, der sich selbst verbirgt Serienleitfaden: /de/blog/2026-02-25-open-world-browser-series-guide