Werte für Clipplingplanes bei perspektivischer Projektion



  • Hallo zusammen,

    ich habe eine quaderförmige grafische Szene mit der Ausdehnung X*Y*Z (diese Werte sind bekannt). Außerhalb dieser Koordinaten muss nichts sichtbar sein. Ich möchte eine perspektivische Darstellung benutzen und verwende OpenGL. Dort gibt es ja die Funktion gluPerspective, die ich verwende. Bisher habe ich die Parameter zNear und zFar experimentell bestimmt, möchte aber, dass diese anhand der oben genannten Ausdehnung des Quaders berechnet werden.

    Leider fehlt mir in diesem Punkt das mathematische verständnis, kurz gesagt: Ich weiß nicht, wie ich das berechnen kann.

    Kennt sich da einer aus?



  • Du moechtest ja den groessten Abstand herausfinden, den einer der Quadereckpunkte "p" von der Projektionsebene hat.
    Dafuer musst Du Dir zunaechst eine Ebenengleichung der Projektionsflaeche aufstellen.
    Dazu brauchst Du die Kameraposition (ist vermutlich gegeben) und die Z-Achse der Kamera als Ebenennormale (deren Matrix kannst Du mit glGet auslesen und dann eben nur den normierten Z-Vektor hernehmen).
    Nun schneidest Du den Strahl von "p" entlang der Normalen mit der Ebene und erhaelst daraus den Abstand.
    Negative Ergebnisse liegen hinter der Projektionsflaeche und interessieren nicht.

    Andersrum formuliert transformierst Du einfach die Z-Koordinate von "p" in den Kameraraum.



  • Hallo hellihjb,

    danke schonmal für die Antwort, ich versuche das mal zu verstehen. Um mein räumliches Vorstellungsvermögen ist es leider nicht allzu gut bestellt, deshalb hab ich arge Probleme mit der Kamera und den Clipping-Ebenen.

    Also, mit Projektionsebene meinst Du die vordere Ebene des View-Frustrums, oder? Und die Z-Achse der Kamera verläuft (in positiver Richtung) vom Kamerapunkt (eye) bis zum Zielpunkt (Center). Die Projektionseben wird damit in einer Entfernung von zNear Einheiten von der Kamera auf der xy-Ebene des Kamerakoordinatensystems plaziert.

    Das ist mein aktueller Wissensstand (bzw. "Glaubensstand"). Stimmt das soweit?

    Wenn ja, wie rechne ich damit?

    Angenommen, meine Szene befindet sich auf allen drei Achsen im Intervall [0, 10] und meine Kamera schaut von (15,15,15) auf den Ursprung (0,0,0). Wie ginge es dann weiter?



  • Du nimmst Dir den Vektor von der Kameraposition zum Kameratarget (das ist die Z-Achse der Kamera und der Normalenvektor der Projektionsebene).
    Die Kameraposition ist wiederum ein Punkt auf der Projektionsebene und daraus kannst Du die Ebenengleichung in hessescher Normalform bestimmen.
    Dann brauchst Du nur noch den Punkt (x,y,z) in die Gleichung einsetzen:

    double distance= a*x + b*y + c*z + d;
    


  • hellihjb schrieb:

    Du nimmst Dir den Vektor von der Kameraposition zum Kameratarget (das ist die Z-Achse der Kamera und der Normalenvektor der Projektionsebene).

    Soweit klar.

    hellihjb schrieb:

    Die Kameraposition ist wiederum ein Punkt auf der Projektionsebene und daraus kannst Du die Ebenengleichung in hessescher Normalform bestimmen.

    Das verstehe ich jetzt nicht. Ich denke, wir reden von sowas wie hier. Die Projektionsebene wäre in dem Bild die grüne Fläche. Die Kamera hat aber einen gewissen Abstand zu dieser Ebene (nämlich genau zNear) und ist somit kein Punkt auf der Projektionsebene.

    Oder seh ich das falsch?



  • hellihjb schrieb:

    Die Kameraposition ist wiederum ein Punkt auf der Projektionsebene und daraus kannst Du die Ebenengleichung in hessescher Normalform bestimmen.

    Die Hessische Normalenform wird aber mithilfe des Einheitsnormalenvektors gebildet, nicht mit einem Punkt.

    Mit ger auf der Abbildung grünen Fläche kannst du ja nicht arbeiten, da du dafür ja zNear benötigen würdest. Und wenn du es hättest, wäre es ein unnötiger Rechenschritt.

    Um Grunde ist es so: Du hast den Punkt der Kamera, und die Richtung, in die sie schaut. Daraus baust du eine Ebene (Normalenform, mithilfe des Punktes und dem Richtungsvektor der Kamera als Normalenvektor)
    Daraus bildest du dann, wie bereits gesagt wurde, die hessesche Normalenform (aus dem Normalenvektor den Eineitsvektor bilden).
    Wenn du dann in diese Gleichung einen der Eckpunkte einsetzt, erhälst du den Abstand dieses Punktes zur Ebene.



  • Der Abstand der Far-Clipping-Plane wird vom Ursprung aus angegeben. Darum kann man den Abstand der Projektionsebene vom Projektionszentrum einfach vernachlaessigen.



  • Ja, aber wenn wir zNear nicht haben, können wir damit ja nicht rechnen.



  • "zNear" ist der Abstand der Near-Clipping-Plane vom Projektionszentrum (Ursprung).
    Wir moechten aber den Abstand der Far-Clipping-Plane vom Ursprung setzen.
    Wozu brauchst Du jetzt "zNear"?



  • Ok, also wenn k die Kameraposition (als Vektor) ist und t das Ziel, auf das die Kamera ausgerichtet ist, n = (k - t) / |k-t| der normierte Normalenvektor der Kameraebene, welcher von der Ebene wegzeigt.

    Für die Hessesche Normalform bilde ich laut der Formel bei Wikipedia das Skalarprodukt aus n und k und erhalte d, was den Abstand der Ebene zum Ursprung des Koordinatensystems angibt.

    Wenn k = (15,15,15) und t = (0,0,0) ist, dann ist n = (0.578,0.578,0.578). Das Skalarprodukt der beiden wäre d = 25.981. Aber wie gehts dann weiter?

    Nachtrag: Es geht mir darum, beides zu berechnen. Normalerweise sollte man zNear vernachlässigen können, aber in manchen Fällen (wenn man weit weg von der Szene ist z.B.) eben nicht. Außerdem gehts mir nicht darum, irgendwelche halbwegs guten Werte zu bekommen, sondern um das Verständnis, das mir (wie man sieht) fehlt.



  • Du hast von Projektionsebene geredet, was ja die Near-Clipping-Ebene ist. Wir rechnen aber mit dieser Ebene nicht, da wir zNear nicht haben. Wir rechnen mit der Ebene, die den gleichen Normalenvektor hat wie diese, aber in der sich die Kamera befindet.



  • also, mal ganz mathematisch^^

    wir haben Punkt K:

    K(k1, k2, k3)
    

    Richtungsvektor R der Kamera, Normalenvektor der Ebene:

    R(r1, r2, r3)
    

    -> Daraus gebildet den Normaleinheitsvektor:

    N(n1, n2, n3)
    

    Daraus bilden wir jetzt die hessesche Normalenform der Ebene:

    (x - K) * N = 0
    
    bzw.
    
    (x - (k1, k2, k3)) * (n1, n2, n3) = 0
    

    für den Vektor x kannst du einsetzen (x, y, z), so dass sich am Ende ergibt:

    (x - k1, y - k2, z - k3) * (n1, n2, n3) = 0
    

    Da wendest du jetzt richtigerweise das Skalarprodukt an, so dass rauskommt:

    d = n1(x - k1) + n2(y - k2) + n3(z - k3)
    

    Wenn du dort für (x,y,z) jetzt einen Punkt einsetzt, erhälst du den Abstand dieses Punktes zur Ebene, in der sich die Kamera befindet.
    Jetzt brauchst du ja nur noch zu gucken, welcher Punkt am weitesten entfernt liegt und vor der Kamera ist.

    Wonach du zNear bestimmen willst, verstehe ich aber nicht so ganz. Wenn man außerhalb der Szene ist, wird doch eh nix gerendert?



  • Danke Powerpaule,

    das sieht doch schon mal gut, aus, ich werds morgen mal durchdenken und hoffentlich verstehen.

    zNear will ich deswegen bestimmen, um mein Frustrum nicht unnötig groß zu machen. Angenommen, die Kamera befindet sich weit vor dem Quader, dann reicht ein höherer Wert aus, um alles darzustellen. Wenn die Kamera aber ganz nahe dran (oder gar drinnen) ist, dann muss zNear sehr niedrig sein.

    Aber es sollte ja so funktionieren, dass ich die Abstände für alle meine Eckpunkte bestimme und dann das Minimum als zNear und das Maximum als zFar setze.
    So verstehe ich das nun zumindest 🙂


Anmelden zum Antworten