OpenGL ES 2.0 (WebGL) First Person Kamera, Mathematikprobleme?

Larrywayn

Mitglied
Zunächst wünsche ich allen ein Frohes neues Jahr,

Ich hab ein kleines Verständnisproblem mit der Handhabung einer First Person Kamera.
Ich hatte damals eine Engine in JOGL geschrieben, also mit Opengl 1.x (Fixed-Function-Pipeline).
Dort war die Handhabung einer Kamera etwas einfacher als in WebGL, weil ich einfach die Winkel seperat gespeichert habe, in WebGL möchte ich aber lieber alles mit Matrizen lösen auch um die Übergabe an die Shader zu vereinfachen.

Ich nutze eine eigene Mathelibrary um flexibler zu sein und somit unnötiges weglassen kann. Meine Matrix ist Spaltenweise angeordnet:
Code:
Xa Ya Za Wa
Xa Ya Za Wa
Xa Ya Za Wa
Xp Yp Zp Wp
Xp Yp Zp Wp ist enthält die Positioninformationen

Was ich mache:
Code:
            this.modelViewMatrix.setzeWert(1, 4, this.modelViewMatrix.holeWert(1, 4) + (0 * ((this.accelerationBewegung * this.speed) / faktor)));
            this.modelViewMatrix.setzeWert(2, 4, this.modelViewMatrix.holeWert(2, 4) + (0 * ((this.accelerationBewegung * this.speed) / faktor)));
            this.modelViewMatrix.setzeWert(3, 4, this.modelViewMatrix.holeWert(3, 4) + (1 * ((this.accelerationBewegung * this.speed) / faktor)));
hole Wert aus Matrix setze Spalte, Zeile auf alten Wert + (Bewegung vorhanden * Beschleunigung / FPSFaktor) addieren.
Sollte eigentlich recht logisch sein.
Wobei nur die letzte Zeile etwas macht, da der Vektor den ich nutze (0,0,1) ist. Also eine Verschiebung der Welt / Kamera in Z-Richtung (Y Zeigt nach oben Z nach vorne).
Bis hierher geht auch alles wunderbar auch die Rotation mit einer allgemeinen Rotationsmatrix aus den Mausbewegungen geht wunderbar.

Problem:
Das Problem ist die Vorwärtsbewegung, anstatt eines Fliegen-Modus einen First Person Modus zu erzielen.
Das heißt, dass ich mich nicht in die Blickrichtung der Kamera bewege sondern entlang eines Vektors der gerade nach vorne zeigt, also die Y-Komponente nicht beachtet, nach meinem Verständnis.
Beispiel: Ich gucke nach oben laufe aber dennoch nicht in die Luft sondern auf Bodenhöhe.

Ich habe es bisher geschafft mich auf den Globalen Achsen fix zu bewegen, was aber komisch wirkt, wenn man sich dreht.
Leider habe ich nur veraltete Tutorials gefunden, die meistens jegliche Informationen seperat speichern, als Pitch, Yaw, Roll. Das möchte ich vermeiden, weil ich es auch nicht wirklich brauche, dafür habe ich ja die Matrix.

Alle Ideen die mir logisch erschienen, Kreuzprodukte, Multiplikationen haben wenig sinnvolles gebracht. Meist nur undefinierte Ergebnisse.
Ich weiß, dass es eigentlich ganz einfach sein muss. Vielleicht hat es ja jemand verstanden und eine Idee :)

Mit freundlichen Grüßen
Larrywayn
 

ikosaeder

Teekannen-Agnostiker
Ich habe jetzt nicht viel Ahnung von WebGl, aber mein Ansatz wäre, das du einen Offset definierst, der die Position der Kamera relativ zu einem Ankerpunkt wiedergibt. Dein Ankerpunkt bewegt sich auf dem Boden, die Kamera ist dann z.b. 1,7 m vom Ankerpunkt,normal zur Oberfläche, entfernt.
Du benötigst dafür vermutlich zwei Matrizen, eine, die die Bewegung und Rotation (um 1 Achse) des Ankerpunktes wiedergibt und eine, die die Rotation der Kamera (2 Achsen evt. 3 Achsen) beschreibt.
 

Larrywayn

Mitglied
Die Idee mit den 2 Matrizen klingt auf alle Fälle nicht ganz verkehrt, eine zum Bewegen, die andere für die Ansicht.
Das könnte später, falls auf eine Third-Person Kamera umgestellt werden soll sogar super praktisch sein, dadran hatte ich bisher nicht gedacht.
Dann lösen sich die mathematischen Probleme auch auf soweit die Theorie.
Danke für deine Antwort, ich mache mich ans Werkeln.

--------------------------------
Edit:
Irgendwie macht das alles keinen Sinn oder ich stelle mich total blöd an, bzw. übersehe etwas Wichtiges.

Ich mache aktuell folgendes:
ich hab eine pro Frame Bewegungsupdate Funktion mit folgender Reihenfolge:

- Hole Matrix Spieler
- Hole Matrix Kamera
- Speichere Koordinaten vom Spieler zwischen
- Setze Koordinaten vom Spieler auf 0
- Erstelle eine Rotationsmatrix um die Y-Achse (Vertikale) (bzw. Es entsteht eine Einheitsmatrix, wenn die Maus nicht bewegt wird)
- Matrix Spieler mit Rotations Matrix multiplizieren Ms * Mr
- (Optional: Multipliziere die Kameramatrix mit der Rotations/Spielermatrix: Mk * Mr/Ms, damit die Kamera die gleiche Drehung hat, jedoch ohne Koordinatenverfälschung)
- Setze die alten Koordinaten wieder in die Spielermatrix ein.
- Setze Koordinaten der Kamera auf 0
- Erstelle eine Rotationsmatrix um die X-Achse (bzw. Es entsteht eine Einheitsmatrix, wenn die Maus nicht bewegt wird)
- Matrix Kamera mit Rotations Matrix multiplizieren Mc * Mr
- Setze die alten Koordinaten wieder in die Kameramatrix ein.

- Erzeuge die Bewegung nach Vorne (sofern nötig)
- Erzeuge die Bewegung zur Seite (sofern nötig)
- Erzeuge eine Translationsmatrix
- Multipliziere die Spielermatrix mit der Translationsmatrix Ms* Mt
- Multipliziere die Kameramatrix mit der Translationsmatrix Mc * Mt
oder setzte die Matrix der Kamera direkt auf die Position der Spielerkamera

Je nachdem wie ich das variiere bewegt sich die Kamera nicht mehr, kann sich aber umgucken, oder ich bewege mich, kann mich aber nicht umgucken.
Wenn es dann mal geht, dann kann ich mich dennoch frei in alle Richtungen bewegen, was für mich keinerlei Logik ergibt.
Ich stehe also ganz am Anfang.

Eventuell liegt es auch an den Shadern, welche auch noch mal Multiplikationen durchführen. Aber diese ganze Mathematik macht mich fertig mh
hat noch jemand Erfahrungen damit?
 
Zuletzt bearbeitet:

Larrywayn

Mitglied
Also ich hab jetzt 2 Grundlegende Probleme erkundet:

Zu Einem, wenn ich die Position zuerst setze und dann rotiere, so ändert die erstellte Rotationsmatrix (eine 4x4 Matrix) auch die Werte Position geringfügig.
D.h. die Rotation verschiebt den Punkt mit, wenn auch nur gering, so wird um den Punkt ein paar cm vor der eigentlichen Position gekreist.
Das wirkt beim Bewegen etwas irritierend.

Rotiere ich zuerst und setze dann die Position, kreise ich um den Ursprung egal wohin ich Blicke, was vollkommen logisch und gewollt ist und die Werte der Position sind fix und ändern sich nicht.

Ich hab 2 verschiedene Multiplikationsmethoden und 2 unterschiedliche Methoden zur Erstellung einer Rotationsmatrix ausprobiert, die annähernd das Gleiche liefern.

Zum Anderen lasse ich das Vorhergegangene außer acht und versuche nach oben und unten zu "blicken", dann dreht sich die Ansicht entweder permanent bzw. bewegt sich in den unendlichen Raum oder sie zittert nur kurz und geht in die eigentliche Matrix zurück.

Das Ziel ist eigentlich nur, dass ich eine Matrix habe, die ich im Raum X/Z (Links/Rechts drehen/bewegen) bewege und das auf einer Ebene zu einer definierten Y-Achse (nach Oben) Richtung und mit der ich mich Umblicken (Nach oben/Unten) kann auf der Stelle an der ich stehe.
Da ich am Anfang im Punkt 0/0/0 stehe und eine 4x4 Einheitsmatrix habe wundere ich mich schon ziemlich, dass alle bekannten Tutorials und Funktionen anscheinend Probleme verursachen.
Leider habe ich mit Mathematik nicht alzuviel zu tun, als dass ich komplexere Berechnungen nachvollziehen könnte mh
 

Larrywayn

Mitglied
Vielen Dank für deine Antwort,

die Funktion kenne ich sehr gut und ich habe mir auch Implementierungen davon angeguckt, jedoch muss die Funktion eben händisch nachgebaut werden, weil sie in WebGl nicht vorhanden ist.
In meinem Kopf ergibt das was ich mir dazu erdenke auch immer viel Sinn, die Wirklichkeit der Mathematik ist dann aber doch anders.

Am besten ist wohl sich das Live Beispiel anzugucken
http://tunnistava.systemcloud.de/

Aktuell gibt es sogar eine Spielfigur, welche sich aber immer irgendwie gespiegelt zur Kamera bewegt, sobald sich gedreht wird.
Inzwischen ist der Code auch sehr unübersichtlich geworden und erstreckt sich über viele Dateien, aber die Drehungen finden in der
Steuerungsmanager.js statt, die Mathematik befindet sich in der Matrix.js.

Solange ich mich nicht drehe funktioniert auch alles, aber es könnte eben auch am Shader liegen, der mir die Matrizenberechnung versaut, weil er eine andere Reihenfolge hat und ich deshalb die Berechnung im Code anpassen müsste.
Code:
 gl_Position = projektionsMatrix * modelviewMatrix * transformationsMatrix        * vec4(vertexPosition, 1.0);
                3D zu 2D           Camera Matrix      Objekt Translation/Drehung   lokale VertexPosition im Modell

Grüße
Larrywayn
 
Zuletzt bearbeitet: