3 Stimmen

Projektion eines Bildschirms für eine Kamera

Ich versuche, ein wenig mehr über Vectormath zu lernen, indem ich einen einfachen Raytracer schreibe, und ich habe einiges darüber gelesen, aber was ich nicht finden konnte, ist, wie man die Richtung der primären Strahlen bestimmt. Das klingt wie ein einfaches Problem und ist es wahrscheinlich auch, aber mit meinem derzeitigen Wissen habe ich es nicht herausfinden können.

Ich habe mir überlegt, dass ich eine Kamera brauche (nicht mehr als einen Standort und eine Richtung als Vektoren) und von der Kamera aus die primären Strahlen auf einen Bildschirm vor der Kamera schieße, der das endgültige Bild darstellt. Was ich nicht herausfinden kann, sind die Eckkoordinaten des Bildschirms. Wenn ich den Bildschirm kenne, ist es einfach, die Richtung der primären Strahlen zu bestimmen.

Ich hoffe, dass der Bildschirm mit einfacher Mathematik, die keine Drehmatrizen erfordert, berechnet werden kann. Meine beste Vermutung ist diese:

Ich habe die Richtung der Kamera als Vektor, diese Richtung ist gleich der Normalen der Ebene der Projektionsfläche. Ich habe also die Normale des Bildschirms, und von dort aus kann ich leicht die Mitte des Bildschirms berechnen, die ist:

camera_location + (normal * distance) 

Der Abstand ist der Abstand zwischen dem Bildschirm und der Kamera. Allerdings ist das der Punkt, an dem ich nicht mehr weiterkomme, und ich kann keine Möglichkeit finden, die Eckkoordinaten der Ebene für eine beliebige Richtung der Kamera herauszufinden.

Kann mir jemand von euch hier weiterhelfen? Und wenn meine Methode nicht funktionieren kann, was dann?

1voto

Alnitak Punkte 324207

EDIT: Hier ist etwas Code, der im Vergleich zu dem ursprünglich geposteten wesentlich reduziert ist, weil er die Erstellung einer viewMatrix auslässt. Das war nur für einige einige Scanline-Rendering benötigt und wurde nicht für Ray-Tracing verwendet.

Die eigentliche Arbeit ist die Funktion lookat(), insbesondere die Erstellung der Vektoren "oben" und "rechts". Diese Vektoren müssen senkrecht zueinander stehen und auch zu dem Vektor, der zwischen dem Auge und der Mitte des Bildes verläuft. Die Erstellung dieser Vektoren beruht auf der Funktion "Kreuzprodukt der Vektoren".

Die eigentliche Funktion zum Werfen von Strahlen geht davon aus, dass der Bildschirmausschnitt in Y-Richtung von -0,5 bis +0,5 reicht. Diese Funktion ist ziemlich einfach und besteht lediglich darin, die richtigen Proportionen der Vektoren "Ansicht", "Oben" und "Rechts" zu addieren.

public class Camera {

    protected Point3d       eye;
    protected Point3d       center;

    protected Vector3d      up;
    protected Vector3d      right;
    protected Vector3d      view;

    protected double        fovy;           // half FoV in radians
    protected double        tanf;
    protected double        aspect;

    public Ray castRay(double x, double y) {

        Vector3d dir = new Vector3d(view);
        Vector3d t = new Vector3d();
        t.scale(tanf * x * aspect, right);
        dir.add(t);
        t.scale(tanf * y, up);

        dir.add(t);
        dir.normalize();

        return new Ray(eye, dir);
    }

    /* algorithm taken from gluLookAt */
    public void lookAt(Point3d _eye, Point3d _center, Vector3d _up) {

        eye = new Point3d(_eye);
        center = new Point3d(_center);
        Vector3d u = new Vector3d(_up);

        Vector3d f = new Vector3d(center);
        f.sub(eye);
        f.normalize();

        Vector3d s = new Vector3d();
        u.normalize();
        s.cross(f, u);
        s.normalize();
        u.cross(s, f);

        view = new Vector3d(f);
        right = new Vector3d(s);
        up = new Vector3d(u);
    }

    /* algorithm taken from gluPerspective */
    public void setfov(double _fovy, double _aspect)
    {
        fovy = Math.toRadians(_fovy) / 2.0;
        tanf = Math.tan(fovy);
        aspect = _aspect;
    }
}

0voto

Ich danke Ihnen für die Informationen. Ich persönlich fühle mich mit Matrixtransformationen nicht sehr wohl und möchte sie so weit wie möglich vermeiden. Aus Ihrem Beitrag entnehme ich jedoch, dass Transformationen die einzige Möglichkeit sind, das zu tun, was ich tun möchte? Das wäre zu schade, da ich dachte, ich war ziemlich nah (ich habe die normale und Mittelpunkt des Bildschirms) und würde eine reine Vektor-Mathematik-Lösung gefallen haben.

Ich werde versuchen, Ihren Code zu übernehmen, aber leider weiß ich nicht genau, was in Ihren Objekten an einigen Stellen intern vor sich geht, vor allem in den Matrix4d-Objekten.

PS: Wenn Sie auf eine Antwort auf StackOverflow als Ersteller der Frage antworten möchten, müssen Sie dann einen Kommentar zu dieser Antwort abgeben, oder ist es in Ordnung, eine neue "Antwort" zu erstellen?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X