2013-08-29 40 views
5

頂点ごとにノーマルを計算しようとしています。 しかし私は何か間違っています。私は、コードを実行すると、私はこれを参照してください。ここでは頂点ごとにノーマルを計算するOpenGL

enter image description here

を現在の頂点とvertex2は、現在の頂点後の頂点である前にvertex1が頂点であることに注意してください、私のコードです。

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

頂点ごとではなく、三角形ごとに法線を計算しています。実際には、あなたが投稿した画像の中の "固体"の法線をはっきりと見ることができます。

"滑らかな"法線を計算するには、各頂点に、その頂点に隣接する三角形の法線の平均である法線を割り当てる必要があります。

ここには、頂点に隣接する2つの辺の間の角度に基づいて法線の加重平均を計算する擬似コードがあります。 (たぶん誰かが三角形の面積を体重として使っているかもしれませんが、それを普遍的に受け入れられる方法があるかどうかわかりません)。

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、しかし、もし私の顔が三角形ではなかったら?ポリゴンから三角形を見つける必要がありますか? – user2320928

+1

@ user2320928現代のOpenGLでは、常に三角形で作業​​する方が良いです。だから法線を計算する前に顔を三角測量する必要があります。 – sbabbi

関連する問題