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.