Generando programáticamente vértices normales

11

Estoy trabajando con la API de cara de Kinect, que proporciona una variedad de vértices e índices para triángulos que se representarán para hacer la imagen de la cara.

El no de vértices y su orden en la matriz, así como los índices dados por kinect son siempre constantes.

Sin embargo, la API no proporciona información sobre datos UV y normales de vértices.

La aplicación requiere que mantenga el orden de vértices tal como lo indica el kinect, ya que sus posiciones en el espacio 3D cambian según el movimiento facial, por lo que la generación de UV y normales en un software de edición 3D está fuera de discusión.

Logré generar UV proyectando las posiciones de vértice en un plano 2D ya que había muy pocos vértices en el mismo plano.

Sin embargo, no sé cómo generar vértices normales para la malla, sin vértice normal la malla de la cara dibuja sin profundidad de sus características desde el punto de vista presencial, aunque la silueta es visible ya que las posiciones de los vértices son correctas.

Entiendo que debido a la ausencia de vértices normales, la iluminación no funcionará correctamente y, por lo tanto, la malla pálida y sin rasgos se ve en este momento.

Entonces, ¿cómo genero vértices normales cuando todo lo que tengo es solo la posición del vértice y el índice de vértices para formar triángulos?

Allahjane
fuente
n = (v1 - v0) x (v2 - v0), donde v0, v1 y v2 son los vértices de la cara (triángulo) en cuestión. El pedido es importante. Normalízalo si realmente lo necesitas. (y xes producto cruzado)
3Dave

Respuestas:

14

Calcular la posición normal de las posiciones de vértice es bastante simple usando el producto vectorial cruzado.

El producto cruzado de dos vectores y v (notado u × v , o a veces u v ) es un vector perpendicular a u y v , de longitud | El | u × v | El | = | El | u | El | | El | v | El | s i n ( θ ) , con θ el ángulo entre u y vuvu×vuvuv||u×v||=||u||||v||sin(θ)θuv. La dirección del vector dependerá del orden de la multiplicación: es lo opuesto a v × u (las dos direcciones perpendiculares al plano).u×vv×u

Si no está familiarizado con el producto cruzado, lo invito a que lo lea y se sienta cómodo con él. Las normales entonces parecerán simples.

Sombreado plano normales

Si tiene un triángulo , A B × A C es un vector perpendicular al triángulo y con una longitud proporcional a su área. Como lo normal es el vector unitario perpendicular al plano del triángulo, puede obtener lo normal con:ABCAB×AC

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

En código, esto se vería así, n = normalize(cross(b-a, c-a))por ejemplo. Simplemente aplique esto en todas sus caras y tendrá sus normales por cara.

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

Tenga en cuenta que esto supone que los vértices no se comparten entre triángulos. No estoy familiarizado con la API de Kinect; es muy posible que se compartan, en cuyo caso tendría que duplicarlos o pasar a la siguiente solución:

Sombreado suave normales

Después de iluminar con las normales calculadas como anteriormente, notará que los bordes de los triángulos son evidentes. Si esto no es deseable, puede calcular normales suaves, teniendo en cuenta todas las caras que comparten un mismo vértice.

La idea es que si un mismo vértice es compartido por tres triángulos T1T2T3NN1N2N3T1T2NN1N2

¿Recuerdas cómo el producto cruzado es proporcional al área? Si suma los productos cruzados y luego normaliza la suma, hará exactamente la suma ponderada que queremos. Entonces el algoritmo se convierte en:

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)

Esta técnica se explica con más detalle en este artículo por Iñigo Quilez: la normalización inteligente de una malla .


Para más información sobre las normales, vea también:

Julien Guertault
fuente
Le daré una oportunidad lo antes posible y volveré con los resultados
Allahjane
Funcionó Gracias a un hombre, funcionó exactamente como lo quería
Allahjane
@Allahjane: me alegra saber que funcionó bien. :)
Julien Guertault