Unser neues E-Book: Vulkan API Programmierung – Vektoren und Matrizen, Beleuchtung, GLSL Shader, Post Processing

Wieder einmal hatten es die letzten Wochen so richtig in sich – ein neuer Vulkan-Artikel musste pünktlich für das Entwickler-Magazin fertig gestellt werden, und die Arbeiten an meinem neuen E-Book

Vulkan API Programmierung – Vektoren und Matrizen, Beleuchtung, GLSL Shader, Post Processing

wollten und wollten einfach kein Ende nehmen.



Über den nachfolgenden Amazon-Partnerlink gelangen Sie zur Detailseite des neuen E-Books:
Vulkan API Programmierung - Vektoren und Matrizen, Beleuchtung, GLSL Shader, Post Processing

Vulkan-Framework-Demoprogramm 2 (Advanced Lighting)

Im Rahmen unseres zweiten Demoprogramms befassen wir uns mit der Weiterentwicklung des von uns verwendeten Beleuchtungssystems (Deferred Lighting). In diesem Zusammenhang gilt es als Ausgangspunkt all unserer weiteren Überlegungen und Bemühungen zunächst einmal die nachfolgende Frage zu beantworten:
Welche Vorgehensweise bietet sich bei der Positionierung und Handhabung einer möglichst großen Anzahl von Lichtquellen in der Spielewelt an?

Die Antwort auf diese Frage ist im Prinzip ganz einfach:

Am besten geht man genauso vor wie bei der Plazierung und Handhabung der 3D-Objekte. Nirgendwo steht geschrieben, dass die in einem Vertex Buffer gespeicherten Daten lediglich die Geometrie eines 3D-Modells widerspiegeln dürfen. Aus diesem Grund führen wir eine Reihe neuer Vertex-Typen ein, die wir innerhalb der für die Beleuchtung verantwortlichen Shader-Programme als Lichtquellen interpretieren:


  • struct CIlluminationDataVertex
  • struct CIlluminationDataAnimatedVertex
  • struct CIlluminationDataAnimatedVertex_2Skeletons
  • struct CIlluminationDataAnimatedVertex_3Skeletons
  • struct CIlluminationDataAnimatedVertex_4Skeletons

In Abhängigkeit von den Eigenschaften dieser „Vertex-Lichtquellen“ lassen sich nun auf einfache Weise eine Reihe von ganz unterschiedlichen Beleuchtungseffekten simulieren – wie beispielsweise (Low Frequency) Schattenwürfe oder GI-Lichteffekte (GI: Global Illumination). Welche Beleuchtungseffekte in diesem Zusammenhang genau berechnet werden sollen, können Sie mit Hilfe der Datei ApplicationSettings.txt festlegen:

GICalculationResolutionWidth: 512
GICalculationResolutionHeight: 512

ShowLowFrequencyShadows(0/1): 0
ShowAdditionalLightSources(0/1): 0
ShowAmbientLightModifiers(0/1): 0
ShowDynamicAmbientLightModifiers(0/1): 1

Vulkan-Framework-Demoprogramm 1

Selbst als größter OpenGL-Fan muss man sich irgendwann einmal eingestehen, dass die OpenGL-API mittlerweile ein wenig in die Jahre gekommen ist. Als im Jahr 1992 die OpenGL-Spezifikation 1.0 veröffentlicht wurde, konnte man von massentauglichen Mehrkernprozessoren oder leistungsfähigen Grafikkarten allenfalls träumen. Da selbst so vermeintlich einfache Dinge wie eine Modifikation der Vertexfarbe mit einem nicht zu unterschätzenden Rechenaufwand verbunden waren, war es nur logisch, OpenGL in Form eines globalen Zustandsautomaten (Global State Machine) zu implementieren und die Werte sämtlicher Grafikpipeline-Parameter so lange beizubehalten, bis seitens des Hauptprogramms eine Änderung erfolgte. In der heutigen Zeit, in der die früher üblichen Single-Thread-Anwendungen längst zum alten Eisen gehören, wird diese einstmals vernünftige Design-Entscheidung jedoch mehr und mehr zu einem Problem. Sofern man den kompletten OpenGL-spezifischen Programm-Code innerhalb eines einzelnen Threads (dem sogenannten Rendering Thread) implementiert, ist man auf der sicheren Seite. Die parallele Verwendung mehrerer Rendering Threads im Rahmen einer OpenGL-Anwendung ist hingegen untersagt, da sich sämtliche Zustandsänderungen innerhalb der einzelnen Threads unweigerlich auch auf alle übrigen Threads auswirken würden. Für die Modellierung von Zustandsänderungen, die auf einen einzelnen Thread beschränkt bleiben sollen, ist ein globaler Zustandsautomat schlicht und ergreifend nicht geeignet. Ein weiteres Problem ergibt sich aus der Tatsache, dass man im Rahmen einer OpenGL-Anwendung sämtliche Arbeitsanweisungen auch einzeln an die Grafikkarte (GPU) übermitteln kann. Während sich besagte Anweisungen bei Verwendung eines einzelnen Rendering Threads noch problemlos interpretieren lassen, kann die Reihenfolge der einzelnen Anweisungen bei Verwendung von mehreren Threads vollkommen durcheinander geraten. Wie Sie sehen können, ist der in der breiten Öffentlichkeit hinlänglich thematisierte unverhältnismäßig hohe OpenGL-Treiber-Overhead nicht der einzige Grund, der für einen Wechsel hin zur neuen Vulkan-API spricht. Der größte Vorteil von Vulkan besteht vielmehr darin, dass wir im Unterschied zu OpenGL bei der Berechnung und Darstellung einer 3D-Szene nicht mehr auf einen einzigen Thread (normalerweise handelt es sich hierbei um den Hauptprogramm-Thread) beschränkt sind.

Alle hier veröffentlichten Demoprogramme erstellen wir mithilfe eines einfachen Vulkan-basierten Frameworks, welches wir mit jedem neuen Programmbeispiel Schritt für Schritt erweitern werden. Nun denn, verschaffen wir uns mal einen kurzen Überblick über die besonders hervorzuhebenden Features unseres ersten Demoprogramms: