Ich lerne einige Grundlagen von OpenGL, frage mich aber, warum es einen Aufruf gibt glNormal
, um die Normalen von Scheitelpunkten festzulegen.
Wenn ich ein einfaches Dreieck wie folgt erstelle:
glBegin(GL_TRIANGLES);
glVertex3f(0,0,0);
glVertex3f(1,0,0);
glVertex3f(0,1,0);
glEnd();
Sollten die Normalen nicht implizit durch den Typ des geometrischen Primitivs definiert werden? Wenn ich keinen Normalwert einstelle, berechnet OpenGL diesen?
Antworten:
Durch
glNormal
mehrmaliges Aufrufen zwischenglBegin/End
können Sie eine Norm pro Scheitelpunkt anstatt pro Grundelement festlegen.Für ein komplexeres Netz, das aus mehreren Dreiecken besteht, möchten Sie, dass die Normalen an einem Scheitelpunkt von den anderen Dreiecken der umgebenden Geometrie und nicht nur von der Normalen des Dreiecks abhängen, zu dem es gehört.
Hier ist ein Beispiel der gleichen Geometrie mit:
(0,0,1)
):Das Standardschattenmodell (
GL_SMOOTH
) bewirkt, dass die Normalen der Eckpunkte des Gesichts über das Gesicht interpoliert werden. Für die Per-Vertex-Normalen ergibt sich eine glatte schattierte Kugel, für die Per-Face-Normalen jedoch Sie das charakteristische facettierte Aussehen.quelle
Nein, der GL berechnet keine Norm für Sie. Es kann nicht wissen, was das normale sein sollte. Ihre Primitiven haben außerhalb der Rasterung (und an einigen anderen Stellen) keine Bedeutung. Der GL weiß nicht, welche Flächen (Dreiecke) einen Scheitelpunkt gemeinsam haben (dies zur Laufzeit zu berechnen ist sehr teuer, ohne unterschiedliche Datenstrukturen zu verwenden).
Sie müssen die "Dreiecksuppe" eines Netzes vorverarbeiten, um gemeinsame Eckpunkte zu finden und Normalen zu berechnen. Dies sollte erfolgen, bevor das Spiel aus Geschwindigkeitsgründen ausgeführt wird.
Es gibt auch Fälle wie harte Kanten, in denen sich geometrisch ein gemeinsamer Scheitelpunkt an der Ecke befindet. Sie möchten jedoch separate Normalen, damit diese korrekt leuchten. Im GL / D3D-Rendering-Modell benötigen Sie dazu zwei separate Eckpunkte (an derselben Position) mit jeweils einer eigenen Normalen.
All dies benötigen Sie auch für UVs und Textur-Mappings.
quelle
Die kurze Antwort ist, dass Sie tatsächlich nicht haben keinen Normalwert einstellen müssen. Normale Vektoren werden nur verwendet, wenn Sie OpenGL-Beleuchtung durchführen (oder vielleicht eine andere davon abhängige Berechnung), aber wenn dies für Sie nicht zutrifft (oder wenn Sie eine andere Methode für die Beleuchtung verwenden, z. B. Lightmaps) ) dann kannst du ganz gerne alle glNormal Anrufe weglassen.
Nehmen wir also an, dass Sie etwas tun, bei dem die Angabe von glNormal Sinn macht, und schauen Sie es sich genauer an.
glNormal kann pro Primitiv oder pro Vertex angegeben werden. Bei pro-primitiven Normalen bedeutet dies, dass alle Normalen für jeden Scheitelpunkt in der primitiven Fläche in die gleiche Richtung weisen. Manchmal ist es das, was Sie wollen, aber manchmal ist es nicht - wo Per-Vertex-Normalen nützlich sind, ist, dass sie jedem Vertex eine eigene Ausrichtung geben.
Nehmen Sie das klassische Beispiel einer Kugel. Wenn jedes Dreieck in einer Kugel die gleiche Norm hätte, wäre das Endergebnis ziemlich facettenreich. Das ist wahrscheinlich nicht das, was Sie wollen, Sie wollen stattdessen eine glatte Schattierung. Sie mitteln also die Normalen für jedes Dreieck, das einen gemeinsamen Scheitelpunkt hat, und erhalten ein glattes, schattiertes Ergebnis.
quelle
Minimales Beispiel , das einige Details der Funktionsweise
glNormal
von diffusem Blitz veranschaulicht .Die Kommentare der
display
Funktion erklären, was jedes Dreieck bedeutet.Theorie
In OpenGL ist jedem Vertex ein normaler Vektor zugeordnet.
Der Normalvektor bestimmt, wie hell der Scheitelpunkt ist. Mit diesem Vektor wird dann bestimmt, wie hell das Dreieck ist.
Wenn eine Oberfläche senkrecht zum Licht steht, ist sie heller als eine parallele Oberfläche.
glNormal
Legt den aktuellen Normalenvektor fest, der für alle folgenden Scheitelpunkte verwendet wird.Der anfängliche Wert für das Normal vor uns allen
glNormal
ist0,0,1
.Normale Vektoren müssen Norm 1 haben, sonst ändern sich die Farben!
glScale
ändert auch die Länge der Normalen!glEnable(GL_NORMALIZE);
bringt OpenGL dazu, ihre Norm für uns automatisch auf 1 zu setzen. Dieses GIF illustriert das sehr schön.Literaturverzeichnis:
quelle
Sie benötigen glNormal, um einige Funktionen coderabhängig zu implementieren. Zum Beispiel möchten Sie vielleicht Normalen erstellen, bei denen harte Kanten erhalten bleiben.
quelle