2010-11-24 22 views
2

J'essaie actuellement d'implémenter des volumes d'ombre dans mon monde opengl. En ce moment, je me concentre uniquement sur le calcul correct des volumes.Mes volumes d'ombre ne bougent pas avec ma lumière

À l'heure actuelle, j'ai une théière qui est rendue, et je peux l'obtenir pour générer des volumes d'ombre, mais ils pointent toujours directement à gauche de la théière. Peu importe où je déplace ma lumière (et je peux dire que je déplace la lumière parce que la théière est éclairée de façon diffuse), les volumes d'ombres vont toujours tout droit à gauche.

La méthode que je utilise pour créer les volumes est:

    1. Trouver les arêtes de silhouette en regardant chaque triangle dans l'objet. Si le triangle n'est pas allumé (testé avec le produit scalaire), ignorez-le. S'il est allumé, vérifiez tous ses bords. Si le bord est actuellement dans la liste des arêtes de silhouette, supprimez-le. Sinon, ajoutez-le.
    2. Une fois que j'ai tous les bords de la silhouette, je traverse chaque bord en créant un quad avec un sommet à chaque sommet du bord, et les deux autres juste éloignés de la lumière.

Voici mon code qui fait tout:

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

je ma lumière défini comme et la principale méthode de génération de volume d'ombre est appelé par:

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

Tout mon code semble auto documenté dans des endroits où je n'ai pas de commentaires, mais s'il y a des parties confuses, faites le moi savoir. J'ai le sentiment que c'est juste une erreur que j'ai regardée. Voici à quoi il ressemble with et without les volumes d'ombre étant rendus.

Répondre

1

Il semblerait que vous ne transformiez pas les volumes d'ombre. Vous devez soit définir la matrice de vue du modèle sur eux afin qu'ils soient transformés le même que le reste de la géométrie. Ou vous devez transformer tous les sommets (à la main) en espace de vue, puis faire le silhouetting et la transformation dans l'espace de vue.

De toute évidence, la première méthode utilisera moins de temps CPU et serait préférable, IMO.