Discover millions of ebooks, audiobooks, and so much more with a free trial

Only $11.99/month after trial. Cancel anytime.

Das Vulkan-API: Teil 3: Umgang mit 3-D-Daten
Das Vulkan-API: Teil 3: Umgang mit 3-D-Daten
Das Vulkan-API: Teil 3: Umgang mit 3-D-Daten
Ebook176 pages1 hour

Das Vulkan-API: Teil 3: Umgang mit 3-D-Daten

Rating: 0 out of 5 stars

()

Read preview

About this ebook

Im seinem dritten shortcut zum Thema Vulkan geht Alexander Rudolph sowohl auf grundsätzliche Themen der 3-D-Grafikprogrammierung als auch auf Besonderheiten des Low-Level-Grafik-API ein.
Dabei erklärt er unter anderem, wie Textur- und Geometriedaten von 3-D-Anwendungen gehandhabt werden und wie man den Datenaustausch zwischen CPU und GPU optimiert. Neben einer umfassenden Beschreibung des richtigen Umgangs mit Grafikdaten wie Bufferobjekten und Texturarrays kommt es dabei auch zu einer ersten Implementierung eines einfachen Frameworks. Schließlich legt er das Fundament, um die genannten Grafikdaten auch innerhalb eines Shader-Programms ansprechen zu können.
LanguageDeutsch
Release dateMar 13, 2018
ISBN9783868027686
Das Vulkan-API: Teil 3: Umgang mit 3-D-Daten

Read more from Alexander Rudolph

Related to Das Vulkan-API

Titles in the series (100)

View More

Related ebooks

Software Development & Engineering For You

View More

Related articles

Reviews for Das Vulkan-API

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    Book preview

    Das Vulkan-API - Alexander Rudolph

    GmbH

    1 3-D-Modelle und Texturen

    Egal, ob im Rahmen der Programmentwicklung bereits die neue Vulkan-Schnittstelle [1], [2] zum Einsatz kommt oder man noch immer auf das althergebrachte OpenGL vertraut: Funktionen zum Laden einer Textur oder eines 3-D-Modells wird man in beiden Fällen vergeblich suchen. Aus diesem Grund setzen wir uns in diesem Kapitel mit der Frage auseinander, wie sich die für die Darstellung einer 3-D-Szene benötigten Daten unabhängig vom jeweils verwendeten API innerhalb einer Grafikanwendung handhaben lassen.

    In den vorangegangenen shortcuts haben wir unser Augenmerk stets auf einen jeweils anderen Aspekt der Vulkan-Programmierung gelegt. Nachdem wir uns zunächst mit den grundlegenden Funktionsprinzipien des neuen Grafik-API auseinandergesetzt haben (Initialisierungsschritte, das Zusammenspiel zwischen einem Command-Buffer und einem Queue-Objekt, Swap Chains, Bufferobjekte und Texturen, Speicherverwaltung, Pipeline- und Renderpass-Objekte, Descriptor Sets, Synchronisierungsmechanismen usw.), drehte sich im folgenden Kapitel schließlich alles um das Multi-Thread-basierte Rendering und Ressourcenmanagement. Im letzten shortcut haben wir darüber hinaus mit dem Entwurf eines einfachen Frameworks (Programmgerüst) [3] für unsere zukünftigen Vulkan-Demoanwendungen begonnen und uns mit den Grundlagen der GLSL-Programmierung (Verwendung von Vertex-, Fragment- sowie Compute-Shader-Programmen) vertraut gemacht. Heute nun werden wir uns mit der Frage auseinandersetzen, wie sich die für die Darstellung einer 3-D-Szene benötigten Modelle und Texturen unabhängig vom jeweils verwendeten Grafik-API innerhalb einer 3-D-Anwendung handhaben lassen. Wie schon gesagt, spielt es in diesem Zusammenhang überhaupt keine Rolle, ob man bereits die neue Vulkan-Schnittstelle verwendet oder weiterhin auf das althergebrachte OpenGL vertraut; Funktionen zum Laden einer Textur oder eines 3-D-Modells sind in beiden Fällen schlichtweg nicht vorhanden.

    3-D-Modelle damals und heute

    An der Vorgehensweise, wie man ein 3-D-Modell (bzw. die zugrunde liegenden Modellteile) konstruiert und die zugehörigen Geometriedaten abspeichert, hat sich seit den 80er- und 90er-Jahren des letzten Jahrtausends, in denen die ersten 3-D-Spiele wie Elite, Frontier: Elite 2 oder Star Wars: X-Wing das Licht der Welt erblickten, nicht wirklich viel verändert. Auch wenn es zwischen den aktuellen Spieletiteln und den Entwicklungen von einst nur noch sehr wenige Gemeinsamkeiten gibt, setzt sich die Oberfläche eines 3-D-Modells nach wie vor aus einer mehr oder weniger großen Anzahl von Dreiecksflächen zusammen, deren Eckpunkte man als Vertices bezeichnet. Für die Beschreibung und Darstellung eines 3-D-Modells sind nun zwei Arten von Informationen erforderlich, die sich getrennt voneinander abspeichern bzw. im Rahmen einer Grafikanwendung mithilfe von zwei separaten Bufferobjekten verwalten lassen. Innerhalb eines Vertexbuffers werden die Geometriedaten sämtlicher Dreieckseckpunkte relativ zum Modellmittelpunkt gespeichert. Hierzu zählen neben den Vertexpositionen und den Texturkoordinaten auch die für die Beleuchtungsberechnungen unverzichtbaren Normalenvektoren, mit deren Hilfe sich die räumliche Orientierung der einzelnen Dreiecksflächen beschreiben lässt. Die Indizes der an den einzelnen Dreiecksflächen beteiligten Vertices werden hingegen in einem zweiten Array, dem so genannten Indexbuffer, gespeichert. Die Vertices mit den Indices 0, 1, 2 definieren Dreieck 1, die Vertices mit den Indices 3, 4, 5 definieren Dreieck 2 usw. Anhand des in Abbildung 1.1 illustrierten Vertex Quads – hierbei handelt es sich um ein besonders einfaches 3-D-Modell, das häufig im Zusammenhang mit der Billboard-Darstellung zum Einsatz kommt – lässt sich das hinter den Vertex- und Indexbufferobjekten stehende Konzept besonders anschaulich nachvollziehen.

    Abbildung 1.1: Texturiertes Vertex Quad

    Grafikprimitiven (Primitive Topologies)

    Die Interpretation der in einem Indexbuffer gespeicherten Daten als eine Liste von Dreiecken, so geschehen bei dem zuvor betrachteten Vertex Quad, stellt jedoch nur eine von mehreren Deutungsmöglichkeiten dar. Die Zusatzinformation, wie die Indexbufferdaten beim Rendering zu interpretieren sind, wird gemeinhin als Grafikprimitive oder als Primitive Topology bezeichnet und muss im Zuge der Initialisierung einer Rendering-Pipeline (eines VkPipeline-Objekts) festgelegt werden. Welche Primitiven wir in diesem Zusammenhang verwenden können, lässt sich anhand von Listing 1.1 und Abbildung 1.2 nachvollziehen. Während man bei der überwiegenden Mehrzahl der 3-D-Modelle für gewöhnlich auf die Dreieckslisten-Primitive (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) zurückgreift und in den zugehörigen Indexbufferobjekten jeweils eine Liste der darzustellenden Dreiecke abspeichert, kommt beim Rendering von einzelnen Punkten, Linien oder Linienzügen hingegen die VK_PRIMITIVE_TOPOLOGY_POINT_LIST- bzw. die VK_PRIMITIVE_TOPOLOGY_LINE_LIST-Primitive zum Einsatz.

    typedef enum VkPrimitiveTopology {

      VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,

      VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,

      VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,

      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,

      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,

      VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,

    [...]

    } VkPrimitiveTopology;

    Listing 1.1: Grafikprimitiven

    Abbildung 1.2: Grafikprimitiven

    Vertexformate

    Die verwendete Grafikprimitive stellt jedoch nicht die einzige Art von Information dar, die für die korrekte Darstellung eines 3-D-Modells erforderlich ist. Um zu verhindern, dass die in einem Vertex-Shader-Programm durchgeführten Berechnungen zu unerwünschten Ergebnissen führen, müssen innerhalb des hierbei verwendeten Vertexbufferobjekts die Attribute aller an einem 3-D-Modell beteiligten Vertices (Vertexattribute: Texturkoordinaten, Normale, Position usw.) in einer genau definierten Reihenfolge (in einem genau definierten Format) abgespeichert worden sein. Anhand der Listings 1.2 bis 1.6 können Sie sich einen Überblick über die wichtigsten Vertexformate verschaffen, die zum jetzigen Zeitpunkt von unserem Vulkan-Framework unterstützt werden.

    Auf das in Listing 1.2 gezeigte CSimpleTexturedScreenSpaceVertex-Format können wir beispielsweise immer dann zurückgreifen, wenn die Vertices wie bei einem Projected Grid (Wasserdarstellung, Terrain-Rendering) oder bei einem Screen-Space-Vertex-Quad (Textausgabe, Darstellung von GUI-Elementen, Hilfsmittel bei der Durchführung von Post-Processing-Berechnungen) bereits im Verlauf der Vertexbufferinitialisierung in den Projektionsraum (Bildraum) transformiert worden sind.

    struct CSimpleTexturedScreenSpaceVertex

    {

      float x, y, z, w;

      float tu, tv;

    };

    Listing 1.2: Vertexformat für bereits in den Bildraum transformierte Vertices

    Vertexattribute der CSimpleTexturedScreenSpaceVertex-Struktur:

    Bildraumposition

    Texturkoordinaten

    Das in Listing 1.3 gezeigte CTexturedVertex-Format lässt sich hingegen immer dann verwenden, wenn bei der Darstellung eines 3-D-Modells auf die Durchführung von Echtzeitbeleuchtungsberechnungen verzichtet werden kann.

    struct CTexturedVertex

    {

      float x, y, z;

      float tu, tv, textureID;

    };

    Listing 1.3: Vertexformat für texturierbare, bereits beleuchtete 3-D-Modelle

    Vertexattribute der CTexturedVertex-Struktur:

    Vertexposition relativ zum Modellmittelpunkt (Modellkoordinaten)

    Texturkoordinaten

    Index der zu verwendenden Textur

    Sofern die Beleuchtung eines 3-D-Modells lediglich im Verlauf der Vertex-Shader-Berechnungen erfolgen soll, bietet sich die Verwendung des in Listing 1.4 gezeigten CTexturedVertexWithNormal-Formats an.

    struct CTexturedVertexWithNormal

    {

      float PosX, PosY, PosZ;

      float NormalX, NormalY, NormalZ;

      float tu, tv, textureID;

    };

    Listing 1.4: Vertexformat für texturierbare 3-D-Modelle (vertexbasierte Beleuchtung)

    Vertexattribute der CTexturedVertexWithNormal-Struktur:

    Vertexposition relativ zum Modellmittelpunkt (Modellkoordinaten)

    Enjoying the preview?
    Page 1 of 1