Skip to content

Eine offene Welt im Browser entwickeln, Teil 1: Wir versuchten zuerst, sie an ihre Grenzen zu bringen

Von Oleg Sidorkin, CTO und Mitgründer von Cinevva

Neu hier? Nutze den Serienleitfaden. Dort erklären wir, was ein Spike ist, und verlinken alle Teile.

Wir entwickeln eine offene Multiplayer-Welt, die vollständig im Browser läuft. Keine Installation, kein App-Store, nur eine URL. Das größte Risiko zu Beginn war offensichtlich: Kann ein Browser eine persistente 3D-Welt überhaupt mit spielbaren Bildraten rendern und dabei noch genug Leistungsreserven für Gameplay, Physik und Netzwerkkommunikation lassen?

Die meisten Open-World-Projekte scheitern in einer vorhersehbaren Reihenfolge. Zuerst entsteht ein gutes Konzept. Dann eine hübsche Szene. Und schließlich stellt man fest, dass das gesamte Frame-Budget bereits aufgebraucht ist, bevor es überhaupt Gameplay gibt.

Wir wollten die Frage nach dem Rendering-Budget beantworten, bevor wir in irgendetwas anderes investierten. Deshalb verzichteten wir bei Spike 1 auf den hübschen Trailer und begannen direkt mit den Messungen.

Spike 1 in einem neuen Tab öffnen ↗ · Quellcode ansehen

Der Aufbau war bewusst einfach. Ein 512 Meter großes Terrain-Mesh, prozedurale Höhen aus überlagertem Sinusrauschen mit einem Abfall zu den Inselrändern, eine Wasserfläche, atmosphärischer Nebel und 500 instanzierte Objekte. Wir verwendeten einfaches WebGL mit Three.js, ACES-Tonemapping und keine Schatten.

Uns war egal, wie es aussah. Entscheidend war, ob die Szene stabil blieb, während wir die Kamera durch sie bewegten.

Aus diesem Spike gingen zwei Erkenntnisse hervor, die das gesamte Projekt prägten.

Erstens bestätigten wir, dass auf Desktop-Systemen tatsächlich genügend Leistungsreserven vorhanden waren, solange wir beim ersten Durchlauf diszipliniert vorgingen. Das gab uns die Zuversicht, später die anspruchsvollere Terrain-Architektur in Angriff zu nehmen.

Zweitens schufen wir eine verbindliche Basislinie. Jeder folgende Spike musste seine Kosten im Verhältnis zu dieser Szene ausweisen. Sah eine neue Funktion gut aus, kostete aber zu viel Leistung, wurde sie nicht übernommen.

Diese Disziplin bei der Basislinie wurde später entscheidend, als wir auf Nahtartefakte, gemischte LOD-Übergänge und Compute-basiertes Meshing stießen. Ohne eine stabile Referenz wirkt jeder Fehler größer, als er tatsächlich ist.

In Teil 2 wechseln wir vom Rendering zum Eingabegefühl. Worker-Physik klingt in Architekturdokumenten großartig. Sie ist aber nur dann relevant, wenn sich die Figur beim Drücken einer Taste weiterhin unmittelbar steuern lässt.

In diesem Kapitel erwähnte Technologien

Heightmap-Terrain. Ein 2D-Raster, in dem jede Zelle einen einzelnen Höhenwert speichert. Die GPU verschiebt im Vertex-Shader ein flaches Mesh und erzeugt dadurch die Terrainoberfläche. Heightmaps sind kompakt (ein Chunk mit 65x65 Zellen benötigt bei 16 Bit etwa 8 KB), GPU-freundlich und schnell zu rendern. Ihre Einschränkung besteht darin, dass sie weder Höhlen noch Überhänge oder andere Oberflächen darstellen können, die sich über sich selbst zurückfalten. Hintergrundinformationen zu den Einschränkungen von Heightmaps und den darauf folgenden Ansätzen findest du in unserem Leitfaden zur Landschaftsgenerierung.

Three.js. Die Rendering-Bibliothek, die wir im gesamten Projekt verwendeten. Three.js abstrahiert WebGL 2 (und später WebGPU) als Szenengraph mit Kameras, Lichtquellen, Materialien und Geometrieobjekten. Die Bibliothek bietet InstancedMesh, um viele Kopien derselben Geometrie mit einem einzigen Draw Call zu rendern, sowie Frustum Culling, PBR-Materialien und Post-Processing. Siehe Three.js auf GitHub. Wie Three.js in den Technologie-Stack einer offenen Browserwelt passt, erklären wir in unserem Leitfaden zu 3D-Technologien im Browser.

InstancedMesh. Eine Funktion von Three.js, die N Kopien derselben Geometrie mit einem einzigen Draw Call rendert, jeweils mit einer anderen Position, Rotation und Skalierung. Die Transformationen der einzelnen Instanzen werden in einem Matrixattribut-Puffer gespeichert. So konnten wir in Spike 1 500 Objekte rendern, ohne 500 separate Draw Calls zu benötigen. Für Vegetation in großem Maßstab führt GPU-gesteuertes Instanz-Culling diesen Ansatz noch weiter. Siehe unseren Landschaftsleitfaden zum GPU-Culling von Vegetation.

Frame-Budget. Bei 60 fps stehen jedem Frame 1000 ms6016.7 ms für alles zur Verfügung: JavaScript-Logik, Physik, Rendering und Compositing. Ein Spike zur „Budgetprüfung“ misst, wie viel davon eine Basisszene verbraucht. Die verbleibende Leistungsreserve für alles, was später hinzukommt, beträgt somit tfeatures=16.7tbaseline. Benötigt die Basisszene bereits 12 ms, bleiben für Gameplay, Physik und Netzwerkkommunikation zusammen nur noch etwa 4,7 ms. Dieser Ansatz stammt aus der AAA-Open-World-Entwicklung, wo GTA V, Skyrim und Elden Ring allesamt aggressives LOD und Streaming einsetzen, um feste Frame-Budgets einzuhalten.


Teil 1 von 12.
Als Nächstes: Teil 2 – Worker-Physik und die Sorge vor Eingabeverzögerungen
Serienleitfaden: /de/blog/2026-02-25-open-world-browser-series-guide