2013-08-29 16 views
5

Próbuję obliczyć normalne dla każdego wierzchołka. Ale robię coś nie tak. Kiedy uruchomić kod widzę tak:obliczyć normalną wartość dla każdego wierzchołka OpenGL

enter image description here

Oto mój kod Zauważ, że vertex1 jest wierzchołek zanim prąd i vertex2 wierzchołek jest wierzchołkiem po bieżącego wierzchołka.

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

Obliczasz wartości normalne na trójkąt, a nie na wierzchołek. Powinieneś zrobić średnią ważoną (używając kąta lub obszaru trójkąta) normalnych każdego trójkąta sąsiadującego z wierzchołkiem i użyć tego. – sbabbi

+0

W modelach czasami są normalne dla każdego wierzchołka i tego właśnie szukam. – user2320928

Odpowiedz

13

Obliczasz normalne na trójkąt, a nie na wierzchołek. W rzeczywistości możesz wyraźnie zobaczyć "solidne" wartości normalne na opublikowanym obrazie.

Aby obliczyć "gładkie" wartości normalne, należy przypisać do każdego wierzchołka wartość normalną, która jest średnią wartości normalnych trójkątów sąsiadujących z tym wierzchołkiem.

Oto trochę pseudokod, który obliczył średnią ważoną normalnych w oparciu o kąt między dwoma krawędziami sąsiadującymi z wierzchołkiem. (Może ktoś użyje obszaru trójkąta jako ciężaru, nie wiem, czy istnieje uniwersalnie akceptowany sposób, aby to zrobić).

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, ale co, jeśli moja twarz nie jest trójkątem? Muszę znaleźć mój trójkąt z wielokąta? – user2320928

+1

@ user2320928 Lepiej jest zawsze pracować z trójkątami w nowoczesnym OpenGL. Więc powinieneś triangulować twarze przed obliczeniem normalnych. – sbabbi

Powiązane problemy