Programaticamente gerando normais de vértice


11

Estou trabalhando com a API de face do Kinect, que fornece uma variedade de vértices e índices para triângulos que devem ser renderizados para criar a imagem da face.

O número de vértices e sua ordem na matriz, bem como os índices dados pelo kinect, são sempre constantes.

No entanto, a API não fornece informações sobre dados UV e normais de vértices.

O aplicativo exige que eu mantenha a ordem do vértice conforme o kinect, pois suas posições no espaço 3D mudam conforme o movimento facial, de modo que gerar UV e normais em um software de edição 3D está fora de questão.

Consegui gerar UV projetando as posições dos vértices em um plano 2D, pois havia muito poucos vértices no mesmo plano.

No entanto, eu não sei como gerar valores normais de vértice para a malha, sem o vértice normal, a malha de face desenha sem profundidade de suas características da perspectiva, embora a silhueta seja visível porque as posições do vértice estão corretas.

Entendo que, devido à ausência de normais de vértices, a iluminação não funcionará corretamente e, portanto, a malha sem característica pálida que parece agora.

Então, como faço para gerar valores normais de vértice quando tudo o que tenho é apenas a posição do vértice e o índice de vértices para formar triângulos?


n = (v1 - v0) x (v2 - v0), em que v0, v1 e v2 são os vértices da face (triângulo) em questão. O pedido é importan. Normalize se você realmente precisar. (e xé produto cruzado)
3Dave

Respostas:


14

Computar o normal a partir das posições dos vértices é bastante simples usando o produto cruzado vetorial.

O produto cruzado de dois vetores e v (observado u × v , ou às vezes u v ) é um vetor perpendicular a u e v , de comprimento | | u × v | | = | | u | | | | v | | s i n ( θ ) , com θ o ângulo entre u e vuvu×vuvuv||u×v||=||u||||v||sin(θ)θuv. A direção do vetor dependerá da ordem da multiplicação: é o oposto de v × u (as duas direções perpendiculares ao plano).u×vv×u

Se você não estiver familiarizado com o produto cruzado, convido você a ler sobre ele e se sentir confortável com ele. Os normais parecerão simples.

Normais de sombreamento simples

Se você possui um triângulo , A B × A C é um vetor perpendicular ao triângulo e com um comprimento proporcional à sua área. Como o normal é o vetor unitário perpendicular ao plano do triângulo, você pode obter o normal com:ABCAB×AC

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

No código, isso seria semelhante, n = normalize(cross(b-a, c-a))por exemplo. Basta aplicar isso sobre todos os seus rostos e você terá seus normais por rosto.

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

Observe que isso pressupõe que os vértices não são compartilhados entre triângulos. Não estou familiarizado com a API do Kinect; é bem possível que eles sejam compartilhados; nesse caso, você precisaria duplicá-los ou seguir para a próxima solução:

Normais de sombreamento suave

Depois de iluminar com normais calculadas como acima, você notará que as arestas dos triângulos são aparentes. Se isso não for desejável, você pode calcular normais suaves, levando em consideração todas as faces que compartilham o mesmo vértice.

T1T2T3NN1N2N3T1T2NN1N2

Lembra como o produto cruzado é proporcional à área? Se você adicionar os produtos cruzados e normalizar a soma, ela fará exatamente a soma ponderada desejada. Então o algoritmo se torna:

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 é explicada com mais detalhes neste artigo por Iñigo Quilez: normalização inteligente de uma malha .


Para mais informações sobre normais, consulte também:


Vou te dar um presente ir o mais cedo possível e voltar com os resultados
Allahjane

Funcionou Graças um homem toneladas, funcionou exatamente eu queria
Allahjane


@ Allahjane: feliz em saber que funcionou bem. :)
Julien Guertault
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.