2010-11-24 8 views
2

Ich versuche derzeit, Schattenvolumina in meiner OpenGL-Welt zu implementieren. Im Moment konzentriere ich mich nur auf die korrekte Berechnung der Volumes.Meine Schattenvolumes bewegen sich nicht mit meinem Licht

Gerade habe ich eine Teekanne, die gerendert wird, und ich kann es bekommen, um einige Schattenvolumen zu generieren, aber sie zeigen immer direkt auf der linken Seite der Teekanne. Egal, wo ich mein Licht bewege (und ich kann sagen, dass ich tatsächlich das Licht verschiebe, weil die Teekanne mit diffusem Licht beleuchtet ist), die Schattenvolumina gehen immer geradeaus nach links.

Die Methode Ich verwende die Volumes zu erstellen ist:

    1. Finden Silhouettenkanten von in dem Objekt an jedem Dreieck suchen. Wenn das Dreieck nicht leuchtet (getestet mit dem Skalarprodukt), überspringen Sie es. Wenn es leuchtet, überprüfen Sie alle Kanten. Wenn sich die Kante derzeit in der Liste der Silhouettenkanten befindet, entfernen Sie sie. Sonst füge es hinzu. Wenn ich alle Silhouettenränder habe, gehe ich durch jede Kante, um ein Viereck mit einem Eckpunkt an jedem Eckpunkt der Kante zu erzeugen, und die anderen beiden erstrecken sich gerade vom Licht weg.

Hier ist mein Code, das alles:

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); 
} 

ich mein Licht als und die Hauptschattenvolumen Erzeugungsverfahren wird durch genannt definiert haben:

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

Alle meine Code selbst scheint dokumentiert an Orten, die ich keine Kommentare habe, aber wenn es verwirrende Teile gibt, lass es mich wissen.

Ich habe das Gefühl, es ist nur ein einfacher Fehler, den ich übersehen habe. Hier ist, wie es aussieht with und without die Schatten Volumes gerendert werden.

Antwort

1

Es scheint, dass Sie die Schattenvolumen nicht transformieren. Sie müssen entweder die Modellansichtsmatrix auf ihnen festlegen, damit sie genauso wie der Rest der Geometrie transformiert werden. Oder Sie müssen alle Scheitelpunkte (von Hand) in den Ansichtsraum transformieren und dann die Silhouette und Transformation im Ansichtsbereich vornehmen.

Offensichtlich wird die erste Methode weniger CPU-Zeit verbrauchen und wäre, IMO, vorzuziehen.

Verwandte Themen