Je travaille avec l'api du visage Kinect, il fournit un tableau de sommets et d'index pour les triangles qui doit être rendu pour créer l'image du visage.
Le nombre de sommets et leur ordre dans le tableau ainsi que les indices donnés par kinect sont toujours constants.
Cependant, l'API ne donne aucune information sur les données UV et les normales des sommets.
L'application me demande de garder l'ordre des sommets tel que donné par le kinect car leurs positions dans l'espace 3D changent en fonction du mouvement du visage, donc générer des UV et des normales dans un logiciel d'édition 3D est hors de question.
J'ai réussi à générer des UV en projetant les positions des sommets sur un plan 2D car il y avait très peu de sommets sur le même plan.
Cependant, je ne sais pas comment générer des normales de sommet pour le maillage, sans sommet normal le maillage de face dessine sans profondeur de ses caractéristiques de la perspective, bien que la silhouette soit visible car les positions des sommets sont correctes.
Je comprends qu'en raison de l'absence de normales de vertex, l'éclairage ne fonctionnera pas correctement et donc le maillage pâle sans relief qu'il a l'air en ce moment.
Alors, comment puis-je générer des normales de sommet quand tout ce que j'ai est juste la position du sommet et l'indice des sommets pour en faire des triangles?
la source
x
est un produit croisé)Réponses:
Le calcul de la normale à partir des positions des sommets est assez simple en utilisant le produit vectoriel croisé.
Le produit croisé de deux vecteurs et (noté , ou parfois ) est un vecteur perpendiculaire à et , de longueur , avec l'angle entre et . La direction du vecteur dépendra de l'ordre de la multiplication: est l'opposé de (les deux directions perpendiculaires au plan).v u × v u ∧ v u v | | u × v | | = |u v u×v u∧v u v ||u×v||=||u||⋅||v||sin(θ) θ u v u×v v×u
Si vous n'êtes pas familier avec le produit croisé, je vous invite à lire à ce sujet et à vous familiariser avec lui. Les normales sembleront alors simples.
Normales d'ombrage plat
Si vous avez un triangle , est un vecteur perpendiculaire au triangle et de longueur proportionnelle à son aire. Puisque la normale est le vecteur unitaire perpendiculaire au plan du triangle, vous pouvez obtenir la normale avec:ABC AB×AC
En code, cela ressemblerait
n = normalize(cross(b-a, c-a))
par exemple. Appliquez simplement ceci sur tous vos visages et vous aurez vos normales par visage.Notez que cela suppose que les sommets ne sont pas partagés entre les triangles. Je ne connais pas l'API Kinect; il est fort possible qu'ils soient partagés, auquel cas vous devrez les dupliquer ou passer à la solution suivante:
Normales d'ombrage lisses
Après un éclairage avec des normales calculées comme ci-dessus, vous remarquerez que les bords du triangle sont apparents. Si cela n'est pas souhaitable, vous pouvez calculer des normales lisses à la place, en prenant en compte toutes les faces qui partagent un même sommet.
L'idée est que si un même sommet est partagé par trois triangles , et par exemple, le normal sera la moyenne de , et . De plus, si est un grand triangle et est un petit, vous voudrez probablement que soit plus influencé par que par .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
Rappelez-vous comment le produit croisé est proportionnel à la surface? Si vous additionnez les produits croisés puis normalisez la somme, elle fera exactement la somme pondérée que nous voulons. Donc l'algorithme devient:
Cette technique est expliquée plus en détail dans cet article d'Iñigo Quilez: la normalisation intelligente d'un maillage .
Pour plus d'informations sur les normales, voir également:
la source