Generazione programmatica di vertici normali


11

Sto lavorando con Kinect Face API, fornisce una serie di vertici e indici per triangoli che devono essere renderizzati per rendere l'immagine della faccia.

Il no dei vertici e il loro ordine nella matrice, nonché gli indici forniti da Kinect è sempre costante.

Tuttavia l'API non fornisce informazioni sui dati UV e sui normali dei vertici.

L'applicazione mi richiede di mantenere l'ordine dei vertici come indicato dal Kinect poiché le loro posizioni nello spazio 3D cambiano secondo il movimento facciale, quindi generare uv e normali in un software di editing 3D è fuori discussione.

Sono riuscito a generare UV proiettando le posizioni dei vertici su un piano 2D poiché c'erano pochissimi vertici sullo stesso piano.

Tuttavia, non so come generare normali vertici per la mesh, senza vertici normali la mesh facciale disegna senza alcuna profondità delle sue caratteristiche dalla prospettiva, sebbene la silhouette sia visibile poiché le posizioni dei vertici sono corrette.

Capisco che a causa dell'assenza di normali vertici l'illuminazione non funzionerà correttamente su di essa e quindi la maglia pallida e priva di sembianze in questo momento.

quindi come posso generare normali vertici quando tutto ciò che ho è solo la posizione del vertice e l'indice dei vertici per farne triangoli?


n = (v1 - v0) x (v2 - v0), dove v0, v1 e v2 sono i vertici della faccia (triangolo) in questione. L'ordine è importante. Normalizzalo se ne hai davvero bisogno. (ed xè prodotto incrociato)
3Dave

Risposte:


14

Calcolare il normale dalle posizioni dei vertici è abbastanza semplice usando il prodotto a croce vettoriale.

Il prodotto incrociato di due vettori e (rilevato , o talvolta ) è un vettore perpendicolare e , di lunghezza , con l'angolo tra e . La direzione del vettore dipenderà dall'ordine della moltiplicazione: è l'opposto di (le due direzioni perpendicolari al piano).uvu×vuvuv||u×v||=||u||||v||sin(θ)θuvu×vv×u

Se non hai familiarità con il prodotto incrociato, ti invito a leggerlo e a metterti comodo. Le normali sembreranno quindi semplici.

Normali di ombreggiatura piatta

Se hai un triangolo , è un vettore perpendicolare al triangolo e con una lunghezza proporzionale alla sua area. Poiché il normale è il vettore unitario perpendicolare al piano del triangolo, puoi ottenere il normale con:ABCAB×AC

N=AB×AC||AB×AC||

Nel codice, questo sembrerebbe n = normalize(cross(b-a, c-a))per esempio. Basta applicare questo su tutti i tuoi volti e avrai le tue normali per viso.

For each triangle ABC
    n := normalize(cross(B-A, C-A))
    A.n := n
    B.n := n
    C.n := n

Si noti che ciò presuppone che i vertici non siano condivisi tra i triangoli. Non ho familiarità con l'API Kinect; è del tutto possibile che siano condivisi, nel qual caso dovresti duplicarli o passare alla soluzione successiva:

Normali di ombreggiatura uniforme

Dopo l'illuminazione con le normali calcolate come sopra, noterai che i bordi del triangolo sono evidenti. Se ciò non è desiderabile, puoi invece calcolare normali normali, prendendo in considerazione tutte le facce che condividono lo stesso vertice.

L'idea è che se uno stesso vertice è condiviso da tre triangoli , e ad esempio, la normale sarà la media di , e . Inoltre, se è un triangolo grande e è piccolo, probabilmente si desidera che sia più influenzato da che da .T 2 T 3 N N 1 N 2 N 3 T 1 T 2 N N 1 N 2T1T2T3NN1N2N3T1T2NN1N2

Ricordi come il prodotto incrociato è proporzionale all'area? Se sommi i prodotti incrociati, quindi normalizzi la somma, farà esattamente la somma ponderata che vogliamo. Quindi l'algoritmo diventa:

For each vertex
    vertex.n := (0, 0, 0)

For each triangle ABC
    // compute the cross product and add it to each vertex
    p := cross(B-A, C-A)
    A.n += p
    B.n += p
    C.n += p

For each vertex
    vertex.n := normalize(vertex.n)

Questa tecnica è spiegata più dettagliatamente in questo articolo di Iñigo Quilez: abile normalizzazione di una mesh .


Per ulteriori informazioni sulle normali, vedere anche:



Ha funzionato Grazie a un uomo di tonnellata, ha funzionato esattamente come volevo
Allahjane il


@Allahjane: felice di sentire che ha funzionato bene. :)
Julien Guertault,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.