2013-08-29 10 views
5

Sto provando il calcolo normale per vertice. Ma faccio qualcosa di sbagliato. Quando eseguo il codice vedo questo:calcolare normale per vertice OpenGL

enter image description here

Ecco il mio codice, noti che vertex1 è vertice prima del vertice corrente e vertex2 è vertici dopo il vertice corrente.

for (int j = 0; j < meshes[t].face[i].numOfPoints; j++) 
      { 
       if (normalSetChange) 
       { 
        vector3D vertex1, vertex2; 

        if ((j < meshes[t].face[i].numOfPoints - 1) && (j > 0)) 
        { 
         vertex1 = vertexes[meshes[t].face[i].vertex[j + 1]] - vertexes[meshes[t].face[i].vertex[j]]; 
         vertex2 = vertexes[meshes[t].face[i].vertex[j - 1]] - vertexes[meshes[t].face[i].vertex[j]]; 
        } 
        else if (j < meshes[t].face[i].numOfPoints - 1) 
        { 
         vertex1 = vertexes[meshes[t].face[i].vertex[j + 1]] - vertexes[meshes[t].face[i].vertex[j]]; 
         vertex2 = vertexes[meshes[t].face[i].vertex[meshes[t].face[i].numOfPoints - 1]] - vertexes[meshes[t].face[i].vertex[j]]; 
        } 
        else if (j > 0) 
        { 
         vertex1 = vertexes[meshes[t].face[i].vertex[0]] - vertexes[meshes[t].face[i].vertex[j]]; 
         vertex2 = vertexes[meshes[t].face[i].vertex[j - 1]] - vertexes[meshes[t].face[i].vertex[j]]; 
        } 

        normalSet = vector3D(vertex1.y * vertex2.z - vertex1.z * vertex2.y, 
              vertex1.z * vertex2.x - vertex1.x * vertex2.z, 
              vertex1.x * vertex2.y - vertex1.y * vertex2.x); 

        normalLength = sqrt(normalSet.x * normalSet.x + normalSet.y * normalSet.y + normalSet.z * normalSet.z); 

        normalSet.x /= normalLength; 
        normalSet.y /= normalLength; 
        normalSet.z /= normalLength; 

        writePolygonLineVCN(PolygonLineVCN(vertexes[meshes[t].face[i].vertex[j]], vertexestexCoordinate[meshes[t].face[i].texCoordinate[j]], normalSet), newFile[workOnCPU]); 
       } 
       else 
        writePolygonLineVCN(PolygonLineVCN(vertexes[meshes[t].face[i].vertex[j]], vertexestexCoordinate[meshes[t].face[i].texCoordinate[j]], vertexesNormals[meshes[t].face[i].normal[j]]), newFile[workOnCPU]); 
      } 
+0

Si stanno calcolando le normali per triangolo, non per vertice. Dovresti fare una media ponderata (usando l'angolo o l'area del triangolo) delle normali di ogni triangolo adiacente a un vertice, e usarlo. – sbabbi

+0

Nei modelli, a volte ci sono normali per ogni vertice e questo è quello che sto cercando. – user2320928

risposta

13

Si stanno calcolando le normali per triangolo, non per vertice. In effetti puoi vedere chiaramente le normali "solide" nell'immagine che hai postato.

Per calcolare le normali "lisce", è necessario assegnare a ciascun vertice un valore normale che è una media delle normali dei triangoli adiacenti a quel vertice.

Ecco uno pseudocodice che ha calcolato la media ponderata delle normali in base all'angolo tra i due bordi adiacenti al vertice. (Forse qualcuno usa l'area del triangolo come peso, non so se esiste un modo universalmente accettato di farlo).

vector3D triangleNormalFromVertex(int face_id, int vertex_id) { 
    //This assumes that A->B->C is a counter-clockwise ordering 
    vector3D A = mesh.face[face_id].vertex[vertex_id]; 
    vector3D B = mesh.face[face_id].vertex[(vertex_id+1)%3]; 
    vector3D C = mesh.face[face_id].vertex[(vertex_id+2)%3]; 


    vector3D N = cross(B-A,C-A); 
    float sin_alpha = length(N)/(length(B-A) * length(C-A)); 
    return normalize(N) * asin(sin_alpha); 
} 

void computeNormals() { 
    for (vertex v in mesh) { 
     vector3D N (0,0,0); 
     for (int i = 0;i < NumOfTriangles;++i) { 
      if (mesh.face[i].contains(v)) { 
       int VertexID = index_of_v_in_triangle(i,v); //Can be 0,1 or 2 
       N = N + triangleNormalFromVertex(i,VertexID); 
      } 
     } 
     N = normalize(N); 
     add_N_to_normals_for_vertex_v(N,v); 
    } 
} 
+0

OK, ma se la mia faccia non fosse un triangolo? Devo trovare il mio triangolo dal poligono? – user2320928

+1

@ user2320928 È sempre meglio lavorare con triangoli nella moderna OpenGL. Quindi dovresti triangolare le tue facce prima di calcolare le normali. – sbabbi

Problemi correlati