2010-11-24 4 views
2

현재 내 OpenGL 세계에서 섀도우 볼륨을 구현하려고합니다. 지금 당장 나는 볼륨을 정확하게 계산하는 데 초점을 맞추고 있습니다.내 그림자 볼륨이 내 빛과 함께 움직이지 않습니다.

지금은 렌더링 된 주전자가 있는데, 일부 음영 볼륨을 생성 할 수는 있지만 항상 주전자의 왼쪽을 직접 가리 킵니다. 내 빛을 어디로 옮겨도 (그리고 나는 찻 주전자가 확산 조명으로 켜져있어 실제로 빛을 움직이고 있다고 말할 수 있습니다.), 그림자 볼륨은 항상 곧장 왼쪽으로 이동합니다.

내가 볼륨을 만드는 데 사용하고 방법은 다음과 같습니다 객체의 모든 삼각형보고에 의해

    1. 찾기 실루엣 모서리. 삼각형이 켜지지 않으면 (내적 제품으로 테스트 한 경우) 건너 뜁니다. 켜져 있으면 모든 가장자리를 확인하십시오. 모서리가 현재 실루엣 모서리 목록에 있으면 제거하십시오. 그렇지 않으면 추가하십시오.
    2. 실루엣 가장자리가 모두 갖추어지면 가장자리의 각 꼭지점마다 하나의 정점이있는 쿼드가 만들어지고 나머지 두 개는 빛으로부터 멀리 확장됩니다.

    void getSilhoueteEdges(Model model, vector<Edge> &edges, Vector3f lightPos) { 
    
        //for every triangle 
        // if triangle is not facing the light then skip 
        // for every edge 
        // if edge is already in the list 
        // remove 
        // else 
        // add 
    
        vector<Face> faces = model.faces; 
    
        //for every triangle 
        for (unsigned int i = 0; i < faces.size(); i++) { 
         Face currentFace = faces.at(i); 
    
         //if triangle is not facing the light 
         //for this i'll just use the normal of any vertex, it should be the same for all of them 
         Vector3f v1 = model.vertices[currentFace.vertices[0] - 1]; 
         Vector3f n1 = model.normals[currentFace.normals[0] - 1]; 
    
         Vector3f dirToLight = lightPos - v1; 
         dirToLight.normalize(); 
    
         float dot = n1.dot(dirToLight); 
         if (dot <= 0.0f) 
          continue; //then skip 
    
         //lets get the edges 
         //v1,v2; v2,v3; v3,v1 
         Vector3f v2 = model.vertices[currentFace.vertices[1] - 1]; 
         Vector3f v3 = model.vertices[currentFace.vertices[2] - 1]; 
    
         Edge e[3]; 
         e[0] = Edge(v1, v2); 
         e[1] = Edge(v2, v3); 
         e[2] = Edge(v3, v1); 
    
         //for every edge 
         //triangles only have 3 edges so loop 3 times 
         for (int j = 0; j < 3; j++) { 
          if (edges.size() == 0) { 
           edges.push_back(e[j]); 
           continue; 
          } 
    
          bool wasRemoved = false; 
          //if edge is in the list 
          for (unsigned int k = 0; k < edges.size(); k++) { 
           Edge tempEdge = edges.at(k); 
           if (tempEdge == e[j]) { 
            edges.erase(edges.begin() + k); 
            wasRemoved = true; 
            break; 
           } 
          } 
    
          if (! wasRemoved) 
           edges.push_back(e[j]); 
         } 
        } 
    } 
    
    void extendEdges(vector<Edge> edges, Vector3f lightPos, GLBatch &batch) { 
        float extrudeSize = 100.0f; 
        batch.Begin(GL_QUADS, edges.size() * 4); 
        for (unsigned int i = 0; i < edges.size(); i++) { 
         Edge edge = edges.at(i); 
    
         batch.Vertex3f(edge.v1.x, edge.v1.y, edge.v1.z); 
         batch.Vertex3f(edge.v2.x, edge.v2.y, edge.v2.z); 
    
         Vector3f temp = edge.v2 + ((edge.v2 - lightPos) * extrudeSize); 
         batch.Vertex3f(temp.x, temp.y, temp.z); 
    
         temp = edge.v1 + ((edge.v1 - lightPos) * extrudeSize); 
         batch.Vertex3f(temp.x, temp.y, temp.z); 
        } 
        batch.End(); 
    } 
    
    void createShadowVolumesLM(Vector3f lightPos, Model model) { 
        getSilhoueteEdges(model, silhoueteEdges, lightPos); 
        extendEdges(silhoueteEdges, lightPos, boxShadow); 
    } 
    

    내 빛과 같이 정의하고 주요 섀도우 볼륨 생성 방법에 의해 호출됩니다 :

    Vector3f vLightPos = Vector3f(-5.0f,0.0f,2.0f); 
    createShadowVolumesLM(vLightPos, boxModel); 
    

    내 코드의 모든 자기 보인다 여기

모두를 수행 나의 코드 장소에 문서화되어있어 의견이 없지만 혼란스러운 부분이 있으면 알려주십시오.

나는 그것이 지나치게 단순한 실수라고 생각합니다. 여기에 withwithout과 같이 보이는 그림자 볼륨이 렌더링됩니다.

답변

1

섀도우 볼륨을 변환하지 않는 것 같습니다. 나머지 도형과 동일하게 변형되도록 모델 뷰 매트릭스를 설정해야합니다. 또는 모든 정점을 (수동으로) 뷰 공간으로 변환 한 다음 뷰 공간에서 실루엣 및 변환을 수행해야합니다.

분명히 첫 번째 방법은 CPU 시간이 적어지고 IMO가 선호됩니다.

관련 문제