Hi zusammen,
beschäftige mich derzeit auch mit Frustum Culling und da geht etwas gehörig schief (ich vermute den Fehler stark bei der Plane Extraktion)
nach mehreren Stunden debugging bin ich leicht am verzweifeln, vielleicht erblickt jemand von euch ja den Fehler.
Mein Ziel ist es die 6 Ebenen in HNF zu erhalten, wobei die Normale ins Frustum zeigen soll.
Danach Cullen gegen irgendeine Form von Bounding Volume (imo Spheres).
Vorsicht ich beschreibe alles in OpenGL, dass bedeutet Column-order bei Matrizen.
Mein Vorgehen derzeit ist:
Step 1: Extraktion der Planes aus View- und Projektions-Matrix
Step 2: Planes mit inverserer Modeltransformation des Bounding Volumes in selbes Koord-System bringen
Step 3: Simpler Test auf Halbraum der Ebenen
Ein "wenig" Code:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
void Frustum::computeFrustumPlanes(glm::mat4 &view, glm::mat4 &proj)
{
glm::mat4 temp = proj*view; // Achtung OpenGL Column-Order
// GLM Zugriff auf Spalten & Zeilen : temp[column][row]
// Left
_frustumPlanes[0] = Plane(temp[3][0]+temp[0][0],
temp[3][1]+temp[0][1],
temp[3][2]+temp[0][2],
temp[3][3]+temp[0][3]);
// Right
_frustumPlanes[1] = Plane(temp[3][0]-temp[0][0],
temp[3][1]-temp[0][1],
temp[3][2]-temp[0][2],
temp[3][3]-temp[0][3]);
// Top
_frustumPlanes[2] = Plane(temp[3][0]-temp[1][0],
temp[3][1]-temp[1][1],
temp[3][2]-temp[1][2],
temp[3][3]-temp[1][3]);
// Bottom
_frustumPlanes[3] = Plane(temp[3][0]+temp[1][0],
temp[3][1]+temp[1][1],
temp[3][2]+temp[1][2],
temp[3][3]+temp[1][3]);
// Near
_frustumPlanes[4] = Plane(temp[3][0]+temp[2][0],
temp[3][1]+temp[2][1],
temp[3][2]+temp[2][2],
temp[3][3]+temp[2][3]);
// Far
_frustumPlanes[5] = Plane(temp[3][0]-temp[2][0],
temp[3][1]-temp[2][1],
temp[3][2]-temp[2][2],
temp[3][3]-temp[2][3]);
|
Der Plane Konstruktor macht folgendes (Die Plane wird intern beschrieben als dot(normal,X) = constant:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
|
Plane::Plane(const float a, const float b, const float c, const float d)
{
normal = glm::vec3(a,b,c);
float l = glm::length(normal);
normal/=l;
constant = d/l;
}
|
Beim Culling wird dann wie gesagt die inverse Transformation der ModelMatrix des BV auf die Ebene angewandt
Bin vermutlich blind vor lauter Coding und bin dankbar über jedes Paar Augen das eventuell einen Fehler findet (auch logische Fehler sind nicht ganz ausgeschlossen bei meinem Vorgehen
)
Viele Grüße und schönes WE zusammen
Sc4v