Du bist nicht angemeldet.

Werbeanzeige

1

07.11.2013, 18:28

Verständnisfrage beim Frustum Culling

Hallo zusammen!

Zurzeit beschäftige ich mich mit dem Frustum Culling. Ich möchte dazu den Clip Space Ansatz verwenden.
Jetzt habe ich dabei eine Verständnisfrage.

Ich verwalte die Szene mit einen Szenegraphen, wobei jeder Knoten eine Model-Matrix hat. Die Kamera ist auch ein Knoten in dem Graphen. Die View-Matrix ist dabei die Inverse der Model-Matrix der Kamera.
Die Projektions-Matrix sieht so aus:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
float fov = 45.0f;
float aspect = 1.0f;
float near = 0.1f;
float far = 100.0f;
float y_scale = (float) (1f / Math.tan(Math.toRadians(fov / 2f)));
float x_scale = y_scale / aspect;
float frustum_length = far - near;

// Matrix ist eine Einheitsmatrix 4x4
matrix.m00 = x_scale;
matrix.m11 = y_scale;
matrix.m22 = -((far + near) / frustum_length);
matrix.m23 = -1;
matrix.m32 = -((2 * near * far) / frustum_length);
matrix.m33 = 0;


Die Koeffizienten der Ebenen erstelle ich dann, wie in der Webseite beschrieben.

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
42
43
44
Matrix4f a = Matrix4f.mul(projection, view, null);

// left
coefficients[0] = new Vector4f(
    a.m00 + a.m30, 
    a.m01 + a.m31, 
    a.m02 + a.m32, 
    a.m03 + a.m33);
// right
coefficients[1] = new Vector4f(
    -a.m00 + a.m30, 
    -a.m01 + a.m31, 
    -a.m02 + a.m32, 
    -a.m03 + a.m33);

// bottom
coefficients[2] = new Vector4f(
    a.m10 + a.m30, 
    a.m11 + a.m31, 
    a.m12 + a.m32, 
    a.m13 + a.m33);
// top
coefficients[3] = new Vector4f(
    -a.m10 + a.m30, 
    -a.m11 + a.m31, 
    -a.m12 + a.m32, 
    -a.m13 + a.m33);

// near
coefficients[4] = new Vector4f(
    a.m20 + a.m30, 
    a.m21 + a.m31, 
    a.m22 + a.m32, 
    a.m23 + a.m33);
// far
coefficients[5] = new Vector4f(
    -a.m20 + a.m30, 
    -a.m21 + a.m31, 
    -a.m22 + a.m32, 
    -a.m23 + a.m33);

for (int i = 0; i < 6; i++) {
    coefficients[i].normalise();
}


Wenn ich dann prüfen möchte, ob ein Punkt in dem Frustum liegt, muss ich den Punkt mit den Koeffizienten multiplizieren (Skalarprodukt).

C#-Quelltext

1
2
3
4
5
6
7
8
9
public boolean contains(final Vector4f v) {
    for (int i = 0; i < 6; i++) {
        if (Vector4f.dot(coefficients[i], v) < 0.0f) {
            return false;
        }
    }

    return true;
}


Eigentlich beziehen sich die Ebenen doch auf das Weltkoordinatensystem (WKS). Dann müsste ich doch auch den zu überprüfenden Punkt in das WKS überführen, bevor ich ihn überprüfen kann. Oder mache ich das mit Hilfe dieser Koeffizienten? Eigentlich ja schon, oder? Da stehe ich im Moment auf dem Schlauch. :hmm:

Ich hoffe ihr könnt mir da weiterhelfen.

Gruß,
wozzy

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

2

07.11.2013, 19:09

Extrahier die Planes einfach aus der ViewProjection Matrix anstatt nur aus der Projection Matrix (selbes Verfahren), dann bekommst du die Koeffizienten im World Space... ;)

3

07.11.2013, 20:40

Hmm... das mache ich auch:

C#-Quelltext

1
Matrix4f a = Matrix4f.mul(projection, view, null);

4

12.11.2013, 15:52

Hmm... bin immernoch nicht weiter gekommen.

Ich habe jetzt mal ein kleines Testprogramm gemacht, wo ich alles unwichtige rausgestrichen habe.
Code auf Pastebin
FrustumTest
Frustum

Eclipse-Projekt (.rar, ca. 1,55 MB)

P.S.: Ist das hier Ok, wenn man auch längere Quelltexte postet? Oder lieber auf Pastebin verlinken?

Werbeanzeige