Was ist der Zweck von Indizes beim 3D-Rendering?


11

Angenommen, Sie haben in OpenGL einen 3D-Cube erstellt. Sie implementieren die erforderlichen Scheitelpunktdaten für das Objekt (Cube). Was wäre der Sinn der Verwendung von Indizes?

v

 void CreateCube()
        {
            const Vertex VERTICES[8] =
            {
                { { -.5f, -.5f,  .5f, 1 }, { 0, 0, 1, 1 } },
                { { -.5f,  .5f,  .5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f,  .5f, 1 }, { 0, 1, 0, 1 } },
                { {  .5f, -.5f,  .5f, 1 }, { 1, 1, 0, 1 } },
                { { -.5f, -.5f, -.5f, 1 }, { 1, 1, 1, 1 } },
                { { -.5f,  .5f, -.5f, 1 }, { 1, 0, 0, 1 } },
                { {  .5f,  .5f, -.5f, 1 }, { 1, 0, 1, 1 } },
                { {  .5f, -.5f, -.5f, 1 }, { 0, 0, 1, 1 } }
            };

            const GLuint INDICES[36] =
            {
                0,2,1,  0,3,2,
                4,3,0,  4,7,3,
                4,1,5,  4,0,1,
                3,6,2,  3,7,6,
                1,6,5,  1,2,6,
                7,5,6,  7,4,5
            };

    //....

    glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES), VERTICES, GL_STATIC_DRAW);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(INDICES), INDICES, GL_STATIC_DRAW);

Im obigen Beispiel wird ein Würfel mit den erforderlichen Eckpunkten im Weltraum erstellt. Welche Relevanz haben die Indizes?


1
An vielen Orten werden Sie Leute sehen, die sie Gesichter nennen. Und das sind sie auch. Jede Fläche besteht normalerweise aus 3 Eckpunkten, um ein Dreieck zu bilden. Daher entsprechen jeweils 3 Indizes einem Dreieck im endgültigen Netz. Sie werden als Indizes bezeichnet, da sie hauptsächlich Offsets der tatsächlichen Scheitelpunktinformationen im Scheitelpunktarray sind. Es ist alles, was Sie über Indizes wissen müssen, denke ich :)
Grimshaw

Antworten:


24

Es gibt Indizes, um den für die Darstellung eines 3D-Modells erforderlichen Speicherbedarf zu verringern, ähnlich wie Farbpaletten verwendet werden können, um den Speicherbedarf eines 2D-Bilds zu verringern.

Durch die Indizierung können Sie vermeiden, dass eine vollständige Definition eines Scheitelpunkts wiederholt wird, wenn Sie die Daten dieses Scheitelpunkts duplizieren müssen, wie dies normalerweise für ein komplexes Modell erforderlich ist.

Moderne 3D-APIs rendern mit Dreiecken. Jede Seite eines Würfels benötigt zwei Dreiecke:

A--B 
|\ |   This cube face has two triangles:
| \|   ABD and ADC.
C--D

Um diese Fläche ohne Indizes anzugeben, müssen Sie die Scheitelpunkte angeben A, B, D, A, D, C. Zwei Scheitelpunkte ( Aund D) werden im Scheitelpunktpuffer wiederholt.

Doch mit Indizes, können Sie einen Vertex - Puffer, der nur die erforderlichen Ecken ( A, B, Cund D) und sechs Indizes: 0, 1, 3, 0, 3, 2. Da Indizes im Allgemeinen viel kleiner als Scheitelpunkte sind und sich viele Scheitelpunkte in praktischen Modellen im Allgemeinen wiederholen, kann dies eine erhebliche Platzersparnis bedeuten.

Beachten Sie, dass einige Scheitelpunkte nur Teilattribute gemeinsam nutzen. Wenn Sie beispielsweise einen Würfel mit Texturabbildung rendern, möchten Sie im Allgemeinen eindeutige Texturkoordinaten pro Fläche, sodass Sie mehrere Scheitelpunkte mit derselben Position und unterschiedlichen Texturkoordinaten haben. Diese Menge an Vervielfältigung ist akzeptabel und notwendig; Wenn Sie einen ganzen Satz von Scheitelpunktattributen duplizieren , werden Sie feststellen, dass die Indizierung Vorteile bringt.

Wenn tatsächlich alle Ihre Netzscheitelpunkte zu 100% unterschiedlich sind, haben Indizes keinen Vorteil (tatsächlich würden Sie mehr Speicherplatz für den Verbrauch des redundanten Indexpuffers verwenden). Dies tritt jedoch nicht immer auf.


1
Sollte es stattdessen 0,1,3, 0,1,2 sein?
Trauriger CRUD-Entwickler

0, 1, 3, 0, 3, 2 eigentlich danke (basierend auf A = 0, B = 1, C = 2, D = 3). Ich habe die Antwort aktualisiert.

Vielleicht ist es erwähnenswert, dass auf einem Dreiecksnetz die durchschnittliche Anzahl von Dreiecken, die an einen Scheitelpunkt angrenzen, 6 beträgt.
Arne

7

Die Verwendung von Indizes dient drei Hauptzwecken:

  • Reduzieren des Speicherbedarfs durch Entfernen doppelter Scheitelpunkte aus dem ursprünglichen Netz.
  • Reduzieren von Vertex-Shader-Berechnungen, indem doppelte Scheitelpunkte nur einmal transformiert werden können.
  • Verketten von Grundelementen, wodurch Sie Draw Calls reduzieren können.

Von diesen ist der erste offensichtlich, weil Sie ihn direkt in Ihrem eigenen Code messen können: Wenn ein Netz beispielsweise 50.000 Scheitelpunkte hatte, aber 30.000 davon Duplikate waren, haben Sie eine Speicherersparnis.

Der zweite und dritte Punkt sind nicht so offensichtlich - Sie müssen bereits eine Entscheidung zur Verwendung von Indizes getroffen haben, und Sie müssen Ihren Code profilieren und die Leistung "vor" und "nach" isolieren, um eine Messung dieser Indizes zu erhalten.

Beim zweiten kann die Hardware das Ergebnis kürzlich transformierter Scheitelpunkte zwischenspeichern. Wenn derselbe Scheitelpunkt wie der kürzlich transformierte gefunden wird, kann die zwischengespeicherte Version verwendet werden, anstatt die Berechnungen erneut durchführen zu müssen. Hardware verwendet den Index, um diese zu identifizieren. Daher sind Indizes unbedingt erforderlich, um dieses Verhalten zu ermitteln.

Zum dritten hat jeder von Ihnen getätigte Draw-Aufruf einen CPU-Overhead, unabhängig davon, wie viel GPU-Arbeit erforderlich ist. Wenn alles andere gleich ist, ist das Zeichnen eines 50.000-Mesh-Aufrufs in einem Draw-Aufruf viel schneller als das Zeichnen in 10.000-Draw-Aufrufen. Wenn Ihr Netz jedoch aus mehreren Streifen oder (noch schlimmer) einer Kombination aus Streifen und Fächern besteht, können Sie dies nicht in einem einzigen Zeichenaufruf tun, ohne (1) Indizes zu verwenden oder (2) entartete Dreiecke einzuführen. Da Indizes jedoch viel kleiner als Scheitelpunkte sind, wird im allgemeinen Fall die Verwendung von Indizes bevorzugt.


0

Die Indizes geben an, welche Gruppen von drei Eckpunkten zusammen die Flächen des Würfels bilden. Nicht jeder Satz von drei Eckpunkten des Dreiecks sind Flächen des Dreiecks.

Sie könnten jeden Scheitelpunkt genau einmal verwenden und diejenigen, die in mehr als einem Dreieck verwendet werden, nur viele Male wiederholen. Dies würde jedoch zusätzliche Scheitelpunkttransformationen bedeuten. Mit Indizes transformieren Sie die Scheitelpunkte nur einmal und verwenden sie so oft wie nötig.


Wenn du Dreieck meinst?
Trauriger CRUD-Entwickler

Moderne Grafikhardware rendert alles als Dreiecke.

1
Wenn Sie wirklich verstehen möchten, was los ist, holen Sie sich Millimeterpapier, zeichnen Sie die 3D-Scheitelpunkte und zeichnen Sie Linien zwischen den in INDICES angegebenen Scheitelpunkten.
Ggambett
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.