11 Punkte von GN⁺ 2025-11-24 | 1 Kommentare | Auf WhatsApp teilen
  • Zusammenfassung der Erfahrung, während drei Monaten Vulkan zu lernen und eine kleine Game-Engine mit zwei Demo-Spielen selbst zu implementieren
  • Aufbauend auf bestehender OpenGL-Erfahrung die Komplexität von Vulkan schrittweise bewältigt und Kernfunktionen wie glTF-Loading, Skinning und Shadow Mapping implementiert
  • Die Engine heißt EDBR (Elias Daler’s Bikeshed Engine), besteht aus rund 19.000 Zeilen Code und nutzt moderne Grafiktechniken wie bindless Descriptors, PVP und BDA
  • Der Artikel teilt praktische Implementierungsdetails zu unverzichtbaren Bibliotheken wie vk-bootstrap, VMA, volk sowie zu Pipeline-Mustern, automatisierter Shader-Build-Pipeline und Synchronisationsverwaltung
  • Durch den Umstieg auf Vulkan wurden globaler Status entfernt, explizite Kontrolle, eine bessere Debugging-Umgebung und Konsistenz zwischen GPUs erreicht; künftig sind Render Graph, SDF-Fonts und volumetrische Effekte geplant

Überblick über das Lernen von Vulkan und die Engine-Entwicklung

  • Der Autor begann Grafikprogrammierung im Selbststudium und hatte bereits vor anderthalb Jahren Erfahrung damit, eine 3D-Engine mit OpenGL zu schreiben
  • Die Vulkan-basierte Engine eignet sich für kleine levelbasierte Spiele und ist eher auf Lernen und Experimente als auf Effizienz ausgerichtet
  • Zu Beginn wurde zunächst ein einfaches 3D-Spiel erstellt und anschließend wurden wiederverwendbare Teile herausgelöst und zu einer Engine gemacht
  • Dass das Projekt in drei Monaten abgeschlossen werden konnte, lag daran, dass es keine allgemeine Engine, sondern eine Engine für einen konkreten Zweck war

Lernpfad für Grafikprogrammierung

  • Für Einsteiger wird empfohlen, mit OpenGL zu beginnen und Dinge wie das Anzeigen texturierter Modelle, Blinn-Phong-Beleuchtung und Shadow Mapping zu lernen
  • Als empfohlene Ressourcen werden learnopengl.com, Anton’s OpenGL 4 Tutorials und Vorlesungen von Thorsten Thormählen genannt
  • Betont wird außerdem, wie wichtig das Verständnis von linearer Algebra (Vektoren, Matrizen, Quaternionen) zusammen mit aktuellem OpenGL-4.6-Übungsmaterial ist

Ratschläge gegen Bike-shedding

  • Unnötige Überplanung und Abstraktion vermeiden und am Prinzip „nur das implementieren, was jetzt gebraucht wird“ festhalten
  • Empfohlen wird der Ansatz: erst zum Laufen bringen, später verbessern
  • Es ist effizienter, zuerst ein kleines Spiel fertigzustellen als direkt eine allgemeine Engine zu bauen
  • Komplexen Code oder Strukturen anderer nicht einfach nachahmen, sondern mit einer einfachen Struktur starten

Warum Vulkan gewählt wurde

  • Für AAA-Spiele wird meist DirectX genutzt, für macOS/iOS Metal und im Web WebGPU/WebGL
  • Der Autor bevorzugt Open Source und Standardtechnologien und entschied sich für Vulkan, passend zum Ziel, kleine 3D-Desktop-Spiele zu entwickeln
  • OpenGL wird nicht mehr weiterentwickelt und ist auf macOS eingestellt
  • WebGPU ist zwar kompakter, hat aber Grenzen wie mangelnde Reife, funktionale Einschränkungen und fehlende Unterstützung für bindless und Push Constants

Der Lernprozess mit Vulkan

  • Anfangs fühlte es sich so schwierig an, als würde man „praktisch selbst einen Grafiktreiber schreiben“,
    doch durch Dynamic Rendering, vk-bootstrap und vkguide ist der Einstieg leichter geworden
  • Wichtige Lernressourcen:
    • vkguide.dev (praxisorientiert von den Grundlagen an)
    • TU Wien Vulkan Lecture Series
    • 3D Graphics Rendering Cookbook, Mastering Graphics Programming with Vulkan
  • Im ersten Monat wurden bereits glTF-Loading, Compute-Skinning, Frustum Culling und Shadow Mapping implementiert

Struktur der EDBR-Engine und Frame-Verarbeitung

  • Der Engine-Code umfasst etwa 19.000 Zeilen, dazu kommen 4.600 Zeilen für ein 3D-Spiel und 1.200 Zeilen für ein 2D-Plattformspiel
  • Wichtige Rendering-Schritte:
    • Compute-SkinningCascaded Shadow Mapping (4096×4096)PBR-basierte Geometry Shading
    • Depth ResolvePost FX (tiefenbasiertes Nebel-Rendering)UI-Rendering
  • Alle Grafiksysteme wurden ausschließlich für Vulkan neu geschrieben und nicht mit altem OpenGL-Code vermischt

Praktische Tipps für die Vulkan-Entwicklung

Empfohlene Bibliotheken

  • vk-bootstrap: vereinfacht Initialisierung und Swapchain-Setup
  • Vulkan Memory Allocator (VMA): automatisiert die Speicherverwaltung
  • volk: vereinfacht das Laden von Erweiterungsfunktionen

GfxDevice-Abstraktion

  • Verwaltet VkDevice, VkQueue, VmaAllocator usw. in einem einzigen Objekt
  • Zuständig für Frame-Beginn/-Ende, Erzeugung von Images und Buffern sowie Verwaltung bindless Descriptors

Shader-Verwaltung

  • Verwendung von GLSL, Vorabkompilierung nach SPIR-V zur Build-Zeit mit glslc
  • Mit CMake-DEPFILE werden Shader bei Änderungen automatisch neu gebaut

Pipeline-Muster

  • Jeder Rendering-Schritt ist als Pipeline auf Klassenebene getrennt (init, cleanup, draw)
  • Durch VK_KHR_dynamic_rendering werden Render Passes und Subpasses weggelassen, wodurch die Struktur einfacher bleibt

Programmable Vertex Pulling + Buffer Device Address

  • Ein einziges Vertex-Struct verarbeitet alle Meshes
  • Der Shader greift per buffer_reference direkt auf Buffer zu, ein VAO ist nicht nötig

Bindless Descriptor

  • Mit globalen Texture-Arrays (textures[], samplers[]) erfolgt Sampling auf Basis von Texture-IDs
  • Texture-IDs werden in der Material-Struct gespeichert und per Push Constants übergeben

Upload dynamischer Daten

  • Pro Frame werden GPU-Buffer ausgetauscht oder Daten über CPU-Staging-Buffer übertragen
  • Die Klasse NBuffer verwaltet die Frames-in-Flight-Struktur

Ressourcenbereinigung und Synchronisation

  • Es werden explizite cleanup-Funktionen verwendet; statt automatischer Bereinigung in Destruktoren erfolgt manuelle Verwaltung
  • Mit vkCmdPipelineBarrier2 wird Speichersynchronisation zwischen Passes durchgeführt
  • Ein Render Graph ist für die Zukunft geplant

Beispiele für Implementierungsdetails

Sprite-Rendering

  • Mit bindless Textures und Instancing werden Tausende Sprites in einem Zug gerendert
  • Die Struct SpriteDrawCommand wird in einen GPU-Buffer hochgeladen, anschließend erfolgt vkCmdDraw(6, N)
  • 10.000 Sprites werden in 315μs gerendert

Compute-Skinning

  • Ein Compute-Shader führt Vertex-Deformation auf Basis von Bone-Matrizen und Gewichten aus
  • Für jede Instanz wird ein eigener Output-Buffer erzeugt, der danach im Rendering identisch behandelt wird

Trennung von Spiel und Renderer

  • Die Spiellogik nutzt entt ECS, der Renderer verarbeitet nur DrawCommand-Vektoren
  • Render-Befehle werden über Aufrufe wie drawMesh und drawSkinnedMesh erzeugt

Szenen-Loading und Prefabs

  • Level werden in Blender als glTF aufgebaut, anhand von Namensregeln für Nodes werden Prefabs automatisch gespawnt
  • Prefabs sind in JSON definiert und verweisen auf externe glTF-Dateien

MSAA, UI, ImGui

  • MSAA x8 auf Basis von Forward Rendering wird eingesetzt
  • Ein automatisches Layout-System wurde entwickelt, inspiriert von der Roblox UI API
  • Um das sRGB-Problem von Dear ImGui zu lösen, wurde ein eigenes Vulkan-Backend geschrieben

Weitere Komponenten

  • Für Physik wird Jolt Physics verwendet, außerdem entt für ECS, OpenAL-soft für Audio und Tracy als Profiler

Vorteile des Umstiegs auf Vulkan

  • Durch das Entfernen globalen Status entsteht eine explizite und modulare Codestruktur
  • Validation Layers und RenderDoc-Debugging erleichtern die Fehlersuche
  • Mehr Konsistenz zwischen GPUs und Betriebssystemen sowie vorhersehbareres Verhalten als bei OpenGL
  • Erweiterbarkeit durch neue Shader-Sprachen (slang, shady)
  • Weniger Abstraktion und klarere Kontrolle über die Pipeline verbessern die Wartbarkeit

Ausblick

  • Geplant sind SDF-Fonts, paralleles Image-Loading und Mipmap-Erzeugung, Bloom, volumetrischer Nebel, Animations-Blendings, Render Graph und AO
  • Vulkan zu lernen ist schwierig, hat aber stark dabei geholfen, moderne Grafik-APIs und Engine-Design besser zu verstehen

1 Kommentare

 
GN⁺ 2025-11-24
Hacker-News-Kommentare
  • Seit meinem Beitrag vor einem Jahr hat sich meine Meinung zu Vulkan nicht wesentlich geändert.
    Für Leute, die Low-Level-Kontrolle über die Grafik wollen, ist es vielleicht interessant, aber für mich war es wirklich eine qualvolle API in der Nutzung.
    Ich will immer noch einmal selbst eine Game-Engine bauen, aber schon das initiale Setup von Vulkan macht mir weiterhin Angst.
    Was ich will, ist so etwas wie eine 3D-Version davon, wie SDL mit 2D-Grafik umgeht.
    Wenn man mit SDL 3D machen will, muss man am Ende doch auf OpenGL heruntergehen, und das ist nicht das Niveau, das ich mir wünsche.
    Vielleicht ist WebGPU eine Alternative, mit der ich gern arbeiten könnte.

    • SDL 3.0 hat vor etwa einem Jahr eine GPU-API eingeführt. Sie ist eine Abstraktionsschicht, die mehrere Backends wie Vulkan kapselt, also einen Blick wert.
      Ich habe damit auch eine Engine gebaut, bin aber am Ende wieder zu einer Vulkan-basierten Engine zurückgekehrt, weil ich mehr Kontrolle und Leistung wollte.
      Trotzdem habe ich im SDL-GPU-Code Synchronisationsmuster gelernt, die mir in meiner Vulkan-Engine sehr geholfen haben.
    • Rusts wgpu ist ein Mittelweg, der Abstraktion auf WebGPU-Niveau bietet.
      Es ist leistungsfähiger als OpenGL, aber man muss sich nicht selbst um Details wie Resource Barriers oder Layout Transitions kümmern.
      Ein Teil des Bookkeepings wird zur Laufzeit übernommen, dafür gibt es Einschränkungen wie die Unterstützung nur einer einzigen Queue.
      Vulkan ist schwierig, aber mit Erweiterungen, die von den großen Herstellern unterstützt werden, wird es deutlich besser.
      Trotzdem gibt es weiterhin unnötige Komplexität, etwa weil man Detailkonfigurationen angeben muss, die Treiber dann ignorieren.
    • Als alter OpenGL-Programmierer stimme ich völlig zu.
      Im Moment fehlt eine mittlere API zwischen High-Level-Game-Engines und Low-Level-Vulkan/Metal.
      Wer als Anfänger 3D-Grafik lernen will, braucht eine einfache API auf dem Niveau von „ein Dreieck zeichnen“, bei der man Konzepte wie Shader oder Buffer noch nicht kennen muss.
      Die feingranulare Kontrolle von Vulkan brauchen nur sehr wenige Engine-Entwickler, für die meisten reicht das OpenGL-Niveau völlig aus.
    • Der Versuch, ein „3D wie SDL“ zu bauen, wächst schnell zu einer Full-Stack-Engine heran.
      3D hat weit mehr kombinierbare Elemente als 2D, deshalb ist es schwer, das mit einer einfachen Grafik-API abzudecken.
      OpenGL hatte ursprünglich auch dieses Ziel, wurde am Ende aber ebenfalls komplex.
  • „bike shedding“ bedeutet, sich an Nebensächlichkeiten festzubeißen und dabei die wichtigen Dinge aus dem Blick zu verlieren.
    Das im Originaltext Beschriebene liegt eher in Richtung Feature Creep oder Over-Engineering.

    • Als Autor hätte man auch den Ausdruck „hobby horsing“ verwenden können.
      Damit ist gemeint, dass man den Projektfortschritt blockiert und sich nur auf das persönliche Vergnügen konzentriert.
      „bike shedding“ wird oft damit erklärt, dass man „über die Farbe des Fahrradschuppens entscheidet, bevor das Haus fertig ist“.
    • Man betreibt gewissermaßen bike shedding über das Wort „bike shedding“ selbst.
  • Es hieß zwar, „mit einem Minecraft-Multiplayer-Klon die Engine-Entwicklung zu beginnen ist keine gute Idee“,
    aber tatsächlich bauen viele Leute Minecraft-artige Spiele als ihr erstes Engine-Projekt.
    Bei Voxel-Engines ist das eine Art „Hello, world“.

  • Der Beitrag von damals (2024) erreichte 625 Punkte und 260 Kommentare — Link zum Original

  • Vulkan war das schwierigste Stück Technik, das ich je gelernt habe.
    Es ist so unintuitiv und voller Wiederholungsarbeit, dass es einem den Spaß am Programmieren nimmt.

    • Du bist nicht begriffsstutzig. Vulkan ist eine Low-Level-Chip-Abstraktions-API und ungefähr so unterhaltsam wie eine USB-API.
      Wenn du einfacher anfangen willst, würde ich OpenGL empfehlen, besonders die Versionen vor der Einführung von Shadern.
      Allerdings drängt die Branche OpenGL zunehmend zurück.
    • Mir ging es genauso, als ich angefangen habe, Vulkan zu lernen.
      Ich bin nur Tutorials gefolgt und habe Code abgeschrieben, ohne die Konzepte zu verstehen.
      Deshalb bin ich auf WebGPU (Google Dawn) umgestiegen, und das war viel einfacher als Vulkan.
      Nachdem ich dank der Einschränkungen von WebGPU die Konzepte verstanden hatte, war es deutlich leichter, wieder zu Vulkan zurückzukehren.
      WebGPU hat keine Push Constants und leidet unter Pipeline-Explosion, aber bei Vulkan sind Synchronisation und Speicherverwaltung schwieriger.
      SDL_GPU ist eine API auf ähnlichem Niveau und daher gut für den Einstieg.
    • Aus demselben Grund bin ich noch nicht von OpenGL auf Vulkan umgestiegen.
      Vulkan ist eine überentwickelte API.
      Eine GPU-Speicherzuweisung, die in CUDA mit einer Zeile möglich ist, verlangt in Vulkan Unmengen an Boilerplate.
      Modernes Vulkan ist deutlich besser geworden, hat aber noch einen langen Weg vor sich.
    • Wenn man typische Vulkan-Codebeispiele sieht, merkt man sofort, dass das nicht für Game-Entwickler gemacht ist.
      Ich hoffe, dass SDL3 oder wgpu zu einer Abstraktionsschicht werden, die diese Komplexität verringert.
      Da Valve SDL3 unterstützt, halte ich diese Richtung für vielversprechend.
    • Vulkan-/DX12-Programmierung ist wirklich schmerzhaft.
      Man sollte sich zuerst fragen: „Muss Grafik multithreaded verarbeitet werden?“
      Falls nicht, gibt es keinen Grund, Vulkan/DX12 zu verwenden.
      Bis echte Performance-Probleme auftreten, ist es viel besser, OpenGL, DX11 oder eine Game-Engine zu nutzen.
  • Ich bin von 3D-/Game-Programmierung fasziniert und schaue oft einigen YouTubern beim Spieleentwickeln zu.
    Aber im Vergleich zu Web-Apps oder DevOps ist das eine deutlich komplexere Welt.
    Pixel-Shader, Compute-Shader, Geometrie, lineare Algebra, sogar PDEs tauchen dort auf.
    TokyoSpliff YouTube-Kanal

  • Ich finde es gut, dass es heute als coole Sache gilt, hobbymäßig eine Game-Engine zu bauen.
    Ich entwickle seit 10 Jahren an meiner eigenen Engine, und es war eine sehr lohnende Erfahrung.

  • Wenn man zum ersten Mal Grafikprogrammierung macht, ist es besser, mit OpenGL anzufangen.
    Ich habe vor 23 Jahren die OpenGL-Tutorials von NeHe gelesen und halte sie bis heute für eines der am besten aufgebauten Lernmaterialien.

  • Zur Klarstellung: Ich bin nicht der Autor des Originalbeitrags und habe nur den Titel beibehalten.