Ich arbeite mit Kinect Face API. Es bietet eine Reihe von Scheitelpunkten und Indizes für Dreiecke, die gerendert werden sollen, um das Gesichtsbild zu erstellen.
Die Anzahl der Eckpunkte und ihre Reihenfolge im Array sowie die von kinect angegebenen Indizes sind immer konstant.
Die API gibt jedoch keine Informationen zu UV-Daten und Scheitelpunktnormalen.
Die Anwendung erfordert, dass ich die vom Kinect vorgegebene Scheitelpunktreihenfolge einhalte, da sich ihre Positionen im 3D-Raum je nach Gesichtsbewegung ändern, sodass das Generieren von UV- und Normalwerten in einer 3D-Bearbeitungssoftware nicht in Frage kommt.
Ich habe es geschafft, UV zu erzeugen, indem ich die Scheitelpunktpositionen auf eine 2D-Ebene projiziert habe, da es nur sehr wenige Scheitelpunkte auf derselben Ebene gab.
Ich weiß jedoch nicht, wie Scheitelpunktnormalen für das Netz generiert werden sollen. Ohne Scheitelpunktnormalen zeichnet das Gesichtsnetz ohne Tiefe seiner Merkmale aus der Perspektive, obwohl die Silhouette sichtbar ist, wenn die Scheitelpunktpositionen korrekt sind.
Ich verstehe, dass aufgrund des Fehlens von Scheitelpunktnormalen die Beleuchtung nicht richtig funktioniert und daher das blasse, merkwürdige Netz, das es gerade sieht.
Wie generiere ich also Scheitelpunktnormalen, wenn ich nur die Scheitelpunktposition und den Index der Scheitelpunkte habe, um daraus Dreiecke zu machen?
quelle
x
ist Kreuzprodukt)Antworten:
Das Berechnen der Normalen aus Scheitelpunktpositionen ist mit dem Vektorkreuzprodukt recht einfach.
Das Kreuzprodukt zweier Vektoren und (notiert oder manchmal ) ist ein Vektor senkrecht zu und mit der Länge , mit der Winkel zwischen und . Die Richtung des Vektors hängt von der Reihenfolge der Multiplikation ab: ist das Gegenteil von (die beiden Richtungen senkrecht zur Ebene).u u × v u ∧ v u v | | u × v | | = | | u | | ⋅ | | v | | s i n ( & thgr ; ) & thgr ; u v u × v v × uv u × v u ∧ v u v | | u×v | | = | | u | | ⋅ | | v | | sin(θ) θ u v u × v v × u
Wenn Sie mit dem Cross-Produkt nicht vertraut sind, lade ich Sie ein, darüber zu lesen und sich damit vertraut zu machen. Normalen werden dann einfach erscheinen.
Flache Schattierungsnormalen
Wenn Sie ein Dreieck , ist ein Vektor senkrecht zum Dreieck und mit einer Länge proportional zu seiner Fläche. Da die Normale der Einheitsvektor senkrecht zur Dreiecksebene ist, können Sie die Normalen erhalten mit:A B × A C.A B C. A B × A C.
Im Code würde dies beispielsweise so aussehen
n = normalize(cross(b-a, c-a))
. Wenden Sie dies einfach auf alle Ihre Gesichter an und Sie haben Ihre Normalen pro Gesicht.Beachten Sie, dass dies voraussetzt, dass Eckpunkte nicht von Dreiecken gemeinsam genutzt werden. Ich bin mit der Kinect-API nicht vertraut. Es ist durchaus möglich, dass sie gemeinsam genutzt werden. In diesem Fall müssten Sie sie duplizieren oder mit der nächsten Lösung fortfahren:
Glatte Schattierungsnormalen
Nach dem Beleuchten mit den oben berechneten Normalen werden Sie feststellen, dass Dreieckskanten sichtbar sind. Wenn dies nicht wünschenswert ist, können Sie stattdessen glatte Normalen berechnen, indem Sie alle Flächen berücksichtigen, die denselben Scheitelpunkt haben.
Die Idee ist, dass, wenn ein gleicher Scheitelpunkt beispielsweise von drei Dreiecken , und geteilt wird , das normale der Durchschnitt von , und . Wenn ein großes Dreieck und ein kleines Dreieck ist, möchten Sie wahrscheinlich, dass stärker von als von .T 2 T 3 N N 1 N 2 N 3 T 1 T 2 N N 1 N 2T1 T2 T3 N N1 N2 N3 T1 T2 N N1 N2
Erinnern Sie sich, wie proportional das Kreuzprodukt zur Fläche ist? Wenn Sie die Kreuzprodukte addieren und dann die Summe normalisieren, ergibt sich genau die gewichtete Summe, die wir wollen. So wird der Algorithmus:
Diese Technik wird in diesem Artikel von Iñigo Quilez ausführlicher erklärt: clevere Normalisierung eines Netzes .
Weitere Informationen zu Normalen finden Sie auch unter:
quelle