2013-08-29 42 views
5

Tôi đang thử tính toán bình thường trên mỗi đỉnh. Nhưng tôi làm điều gì sai. Khi tôi chạy mã Tôi thấy điều này:tính bình thường trên mỗi đỉnh OpenGL

enter image description here

Đây là mã của tôi, Lưu ý vertex1 đó là đỉnh trước khi đỉnh hiện tại và vertex2 là đỉnh sau đỉnh hiện nay.

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

Bạn là các chỉ tiêu tính toán cho mỗi tam giác, không phải trên mỗi đỉnh. Bạn nên làm một trọng số trung bình (bằng cách sử dụng góc hoặc diện tích tam giác) của các normals của mỗi tam giác tiếp giáp với một đỉnh, và sử dụng nó. – sbabbi

+0

Trong các mô hình, đôi khi có bình thường đối với mỗi đỉnh và đó là những gì tôi đang tìm kiếm. – user2320928

Trả lời

13

Bạn là các chỉ tiêu tính toán cho mỗi tam giác, không phải trên mỗi đỉnh. Trong thực tế, bạn có thể thấy rõ ràng các tiêu chuẩn "rắn" trong hình ảnh bạn đã đăng.

Để tính toán các chỉ tiêu "trơn tru", bạn cần chỉ định cho mỗi đỉnh bình thường, là mức trung bình của các bình thường của các hình tam giác liền kề với đỉnh đó.

Dưới đây là một số mã giả, tính toán mức trung bình trọng số của các tiêu chuẩn dựa trên góc giữa hai cạnh kề với đỉnh. (Có lẽ ai đó sử dụng diện tích của tam giác như trọng lượng, tôi không biết nếu có một cách được chấp nhận phổ biến để làm điều đó).

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, Nhưng nếu mặt tôi không phải là một hình tam giác thì sao? Tôi cần phải tìm tam giác của tôi từ đa giác? – user2320928

+1

@ user2320928 Tốt hơn là luôn làm việc với hình tam giác trong OpenGL hiện đại. Vì vậy, bạn nên triangulate khuôn mặt của bạn trước khi bạn tính toán các normals. – sbabbi

Các vấn đề liên quan