2013-08-29 2 views
5

Я пытаюсь вычислить нормальное значение для каждой вершины. Но я делаю что-то неправильно. Когда я запускаю код, который я вижу это:вычислять нормальное значение для каждой вершины OpenGL

enter image description here

Вот мой код, Обратите внимание, что vertex1 является вершиной перед текущей вершиной и vertex2 является вершиной после текущей вершины.

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

Вы вычисляете нормали на треугольник, а не на вершину. Вы должны сделать средневзвешенное (используя угол или площадь треугольника) нормалей каждого треугольника, прилегающего к вершине, и использовать это. – sbabbi

+0

В моделях иногда для каждой вершины есть нормальные, и именно это я и ищу. – user2320928

ответ

13

Вы вычисляете нормали на треугольник, а не на вершину. На самом деле вы можете четко видеть «твердые» нормали в изображении, который вы разместили.

Для вычисления «гладких» нормалей вам нужно назначить каждой вершине нормаль, которая является средним по нормалям треугольников, смежных с этой вершиной.

Вот несколько псевдокодов, которые вычисляли средневзвешенное значение нормалей на основе угла между двумя ребрами, смежными с вершиной. (Возможно, кто-то использует область треугольника как вес, я не знаю, есть ли общепринятый способ сделать это).

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

ОК, Но что, если мое лицо не было треугольником? Мне нужно найти мой треугольник из полигона? – user2320928

+1

@ user2320928 Лучше всегда работать с треугольниками в современном OpenGL. Поэтому вы должны триангулировать свои лица, прежде чем вычислять нормали. – sbabbi