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.