Seite 1 von 2

(gelöst) Weltrotation rückgängig machen

Verfasst: 16.06.2011, 18:46
von Krishty
Hi,

Ich habe eine Transformationsmatrix, die ein Objekt verschiebt und rotiert. Und ich habe die Projektionsmatrix, die das Objekt auf die Bildschirmebene projeziert.

Die Welttransformation möchte ich nun rückgängig machen – aber nur ihren Rotationsanteil. Der Hintergrund ist, dass ich eine Sprite rendern möchte, die zwar an einen bestimmten Ort in der Welt verschoben und entsprechend ihrer Tiefe in der Bildschirmebene projiziert wird, dabei aber ständig den Betrachter anglotzt.

Da gibt es doch bestimmt eine mathematische Abkürzung für, oder? Die ersten 3×3 Werte aus der Welttransformation nehmen, auf 4×4 aufpusten, transponieren und multiplizieren vielleicht? Oder die ersten 3×3 Werte direkt auf die Einheitsmatrix setzen?

(Ich habe eine Hierarchie von Transformationen, darum kann ich nicht einfach die komplette Welttransformation außer dem Translationsteil wegschmeißen :/ Glaube ich jedenfalls.)

Gruß, Ky

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:04
von CodingCat
Die Welttransformation möchte ich nun rückgängig machen – aber nur ihren Rotationsanteil. Der Hintergrund ist, dass ich eine Sprite rendern möchte, die zwar an einen bestimmten Ort in der Welt verschoben und entsprechend ihrer Tiefe in der Bildschirmebene projiziert wird, dabei aber ständig den Betrachter anglotzt.
Heißt das, die Objekte sollen am Ende so aussehen, als seien sie in der Welt nie gedreht worden, oder als seien sie gegenüber dem Betrachter immer fix?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:05
von Krishty
Gegenüber dem Betrachter fix, starren ihn immer an. Mir fällt gerade auf, dass ich dann auch in der View Matrix rumpopeln muss. Die gibt’s ja auch noch :/

Wahrscheinlich muss ich sie also zuerst in der Weltmatrix so setzen, als seien sie nie rotiert worden. Und dann nochmal in der View Matrix so, als hätte sich der Betrachter nie gedreht. Was aufs Gleiche hinausläuft. Nur habe ich die View- und Projektionsmatrix zusammengefasst, autsch :/

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:12
von Schrompf
Du müsstest also quasi den Rotationsanteil der Model-View-Matrix nichten, ohne die Wirkung der Projection Matrix zu beeinflussen. Ich glaube aber, das geht mathematisch gar nicht, wenn Du nicht zumindest eine der beiden Matrizen einzeln da hast. Und wenn Du sie einzeln da hast, ist das Ganze eh ein NoBrainer.

Mal anders gefragt: was genau hast Du eigentlich vor? Kann man das evtl. auch anders erreichen. Und falls Du noch nicht darüber nachgedacht hast: willst Du, dass das Objekt auch dann noch gerade auf den Betrachter schaut, wenn die Kamera seitlich geneigt ist? Wenn nicht, haben wir noch ein Problem.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:18
von Krishty
Schrompf hat geschrieben:Mal anders gefragt: was genau hast Du eigentlich vor?
Dass das Objekt den Betrachter immer frontal anguckt :)
Schrompf hat geschrieben:willst Du, dass das Objekt auch dann noch gerade auf den Betrachter schaut, wenn die Kamera seitlich geneigt ist?
Japp, will ich.

Ich gucke mal, ob ich statt View und Projection nicht World und View zusammenfassen kann. Dann kann ich dort den Rotationsteil vernichten und hätte am Ende nur die Translation mit der Projektion übrig, was hoffentlich zum gewünschten Ergebnis führt.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:20
von CodingCat
Warum überhaupt die Projektionsmatrix? Gesetzt, du kennst die Welt-View-Matrix noch ohne Projektionsmatrix, solltest du mit Welt * View * Welt'^T hinkommen, wobei Welt' die obere 3x3-Weltmatrix homogenisiert und zeilenweise normalisiert darstellt. Sobald du mal durch die Projektionsmatrix bist, hast du ein Problem, weil die in aller Regel weit weg von orthogonal ist.

Wir bauen um: Ach, schon wieder auf die Eingangsverwirrung reingefallen, jetzt haben wir wieder das in der Welt ungedrehte Objekt.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:23
von Krishty
CodingCat hat geschrieben:Warum überhaupt die Projektionsmatrix?
Das Objekt soll den Betrachter zwar immer frontal anstarren, dabei aber immernoch perspektivisch verzerrt werden.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 19:26
von dot
Trivial: Du transformierst die Position deines Sprite mit der WorldView Matrix und renderst das Ding dann nurmehr mit der Projection Matrix an die Stelle.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:04
von Krishty
Schrompf hat geschrieben:Du müsstest also quasi den Rotationsanteil der Model-View-Matrix nichten, ohne die Wirkung der Projection Matrix zu beeinflussen. Ich glaube aber, das geht mathematisch gar nicht, wenn Du nicht zumindest eine der beiden Matrizen einzeln da hast. Und wenn Du sie einzeln da hast, ist das Ganze eh ein NoBrainer.
Habe ich jetzt, kriege es aber trotzdem nicht hin. Wenn ich die View-Matrix transponiere und dann ihre ersten 3×3 Zeilen in die World-Matrix kopiere blickt mich das Objekt zwar immer an, aber seine Achsen sind vertauscht. Negiere ich die drei oder vier Werte in der Hauptdiagonalen, spielt es wieder völlig verrückt.
Achja: Die View Matrix invertiert die Y-Achse, weil irgendjemand so klug war, die komplette Programmlogik vertikal zu invertieren m[
dot hat geschrieben:Trivial: Du transformierst die Position deines Sprite mit der WorldView Matrix und renderst das Ding dann nurmehr mit der Projection Matrix an die Stelle.
Ist so trivial nicht, denn über alles läuft am Ende View × Projection (spart eine Matrixmultiplikation, weil ich fast alles in Software machen muss). Vielleicht ist das jetzt aber echt der Punkt, wo ich komplett auf Software-Transformation umsteige – oder aber ich ziehe die inverse View-Matrix ganz an den Anfang der World Matrix und multipliziere am Ende nur noch mit Projection. Das klingt am einfachsten. Mal gucken, wie ich die View-Matrix invertiert kriege.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:07
von dot
Krishty hat geschrieben:Ist so trivial nicht, denn über alles läuft am Ende View × Projection (spart eine Matrixmultiplikation, weil ich fast alles in Software machen muss). Vielleicht ist das jetzt aber echt der Punkt, wo ich komplett auf Software-Transformation umsteige – oder aber ich ziehe die inverse View-Matrix ganz an den Anfang der World Matrix und multipliziere am Ende nur noch mit Projection. Das klingt am einfachsten. Mal gucken, wie ich die View-Matrix invertiert kriege.
Ich versteh nicht ganz, zumindest die Multiplikation mit der Projection passiert doch sowieso auf der Grafikkarte!? Oder ist das ein Software-Rasterizer!?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:10
von Krishty
Naja, die Reihenfolge ist ja World–View–Projection.

World ändert sich bei mir ständig, weil eine Hierarchie durchgeackert wird und alle Vertices müssen damit in Software transformiert werden. Darum wird View–Projection in einem Satz auf der GPU erledigt.

Ich muss also entweder in World präventiv View invertieren, oder View in der Reihenfolge nach vorne holen indem ich dessen Inverse als Basis für meine World-Hierarchie nehme.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:12
von dot
Krishty hat geschrieben:World ändert sich bei mir ständig und alle Vertices müssen damit in Software transformiert werden.
Die von den Sprites auch!?
Rein aus Interesse: Was renderst du da!?
Krishty hat geschrieben:Darum wird View–Projection in einem Satz auf der GPU erledigt.
Aber für die Sprites wirst du doch so oder so einen anderen Shader verwenden, was hindert dich dran dass der einfach nur mit der Projection Matrix multipliziert!? Über den GeometryShader könntest du evtl. sogar komplett alles auf der GPU erledigen.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:16
von Krishty
dot hat geschrieben:
Krishty hat geschrieben:World ändert sich bei mir ständig und alle Vertices müssen damit in Software transformiert werden.
Warum!? Die von den Sprites auch!?
Weil die Programmlogik davon abhängt, und ja :)
dot hat geschrieben:
Krishty hat geschrieben:Darum wird View–Projection in einem Satz auf der GPU erledigt.
Aber für die Sprites wirst du doch so oder so einen anderen Shader verwenden
Nee :/ Sprites sind Objekte wie alle anderen und zeichnen sich allein dadurch aus, dass sie in der Transformationshierarchie eine Transformation benutzen, die sie immer in Richtung Betrachter blicken lässt. Sie können sogar Kindobjekte haben, die dann wieder transformiert sind. Klingt sinnlos und dämlich, aber ich bin mal wieder die arme Wurst, die gerendert kriegen muss, was andere verbrochen haben. (Obwohl ich das an dieser Stelle zugegebenermaßen sogar enorm elegant finde – wenn ich es denn nur hinkriegen würde …)

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:20
von Alexander Kornrumpf
Reden wir von dem was man früher Billboard nannte und wie haben die das früher gemacht?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:22
von dot
dot hat geschrieben:Nee :/ Sprites sind Objekte wie alle anderen und zeichnen sich allein dadurch aus, dass sie in der Transformationshierarchie eine Transformation benutzen, die sie immer in Richtung Betrachter blicken lässt. Sie können sogar Kindobjekte haben, die dann wieder transformiert sind.
Kindobjekte wieder transformiert = sie schauen auch immer zum Betrachter? Wenn nicht bedeutet das doch dass dein Sprite einfach ein Node wie jeder andere ist der eine normale Transformation wie jeder andere hat!? Inwiefern ist die Position der Vertices deines Sprite dann für die Programmlogik relevant?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:23
von eXile
Krishty hat geschrieben:Ich gucke mal, ob ich statt View und Projection nicht World und View zusammenfassen kann. Dann kann ich dort den Rotationsteil vernichten
Mit \($\mathbf a = (a_{12} \ a_{24} \ a_{34})^{\mathrm T}$\) und \($\mathbf q_i = (q_{1i} \ q_{2i} \ q_{3i})^{\mathrm T}$\) als Spaltenvektoren, sowie dem Skalar \($m = -(\mathbf q_1 \times \mathbf q_3)^*\mathbf q_2$\) erhalten wir:
\($$\left(\!\!\begin{array}{ccc|c}a_{11} & a_{12} & a_{13} & a_{14} \\ a_{21} & a_{22} & a_{23} & a_{24} \\ a_{31} & a_{32} & a_{33} & a_{34} \\ \hline 0 & 0 & 0 & 1 \end{array}\!\!\right)
= \left(\!\!\begin{array}{ccc|c} q_{11} & q_{12} & q_{13} & 0 \\ q_{21} & q_{22} & q_{23} & 0 \\ q_{31} & q_{32} & q_{33} & 0 \\ \hline 0 & 0 & 0 & 1\end{array}\!\!\right)
\cdot \left(\!\!\begin{array}{ccc|c} 1 & 0 & 0 & (\mathbf a \times \mathbf q_2)^* \mathbf q_3/m \\ 0 & 1 & 0 & -(\mathbf q_1 \times \mathbf q_3)^*\mathbf a/m \\ 0 & 0 & 1 & -(\mathbf a \times \mathbf q_2)^*\mathbf q_1/m \\ \hline 0 & 0 & 0 & 1\end{array}\!\!\right)$$\)
Ach du meine Güte, was habe ich denn hier verbrochen. Ich ziehe die Formel erstmal zurück. :oops:

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:23
von Schrompf
Es klingt wie Billboards, in der Tat. Warum zur Hölle machst Du das in Software, anstatt pro Objekt die World Matrix getrennt zu setzen wie alle anderen auch?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:31
von Krishty
Alexander Kornrumpf hat geschrieben:Reden wir von dem was man früher Billboard nannte und wie haben die das früher gemacht?
Ups, ja. Ich muss zugeben, dass ich den Unterschied zwischen Sprite und Billboard garnicht kenne … also eins von den beiden jedenfalls. Wie die das gemacht haben? Die haben sowohl bei der World- als auch bei der View-Matrix die ersten 3×3 Komponenten auf Einheit gesetzt. Das geht bei mir aber nicht, weil bei mir View und Projection in einer Matrix zusammengefasst sind.
dot hat geschrieben:
dot hat geschrieben:Nee :/ Sprites sind Objekte wie alle anderen und zeichnen sich allein dadurch aus, dass sie in der Transformationshierarchie eine Transformation benutzen, die sie immer in Richtung Betrachter blicken lässt. Sie können sogar Kindobjekte haben, die dann wieder transformiert sind.
Kindobjekte wieder transformiert = sie schauen auch immer zum Betrachter?
Nicht zwingend – „immer genau 90° gegenüber dem Betrachter rotiert“ kommt z.B. vor, also als Kind einer Sprite, das gegenüber dem Sprite-Knoten um 90° rotiert ist.
eXile hat geschrieben:Ach du meine Güte, was habe ich denn hier verbrochen. Ich ziehe die Formel erstmal zurück. :oops:
Ich habe sie sowieso nicht verstanden ;)
Schrompf hat geschrieben:Es klingt wie Billboards, in der Tat. Warum zur Hölle machst Du das in Software, anstatt pro Objekt die World Matrix getrennt zu setzen wie alle anderen auch?
Ich mache nicht nur die Billboards/Sprites in Software, sondern die gesamte Welttransformation.

Langsam tendiere ich dazu, View und Projection komplett zu trennen und dann eben die zusätzliche Transformation pro Vertex in Kauf zu nehmen. Aber dann verdoppelt sich glatt die Größe meines Transformationsstapels, weil ich dann auch die View-Matrix jedes Knotens speichern müsste, denn die ändert sich ja, falls der Knoten ein Billboard/Sprite ist.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:34
von dot
Krishty hat geschrieben:Nicht zwingend – „immer genau 90° gegenüber dem Betrachter rotiert“ kommt z.B. vor, also als Kind einer Sprite, das gegenüber dem Sprite-Knoten um 90° rotiert ist.
Ok, d.h. der Sprite Knoten wird tatsächlich immer zum Betracher rotiert und alle Kinder mit ihm!? Das ist dann natürlich blöd...

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:39
von eXile
Mal dumm ins Blaue geschossen: Für die Model-Matrix \($\mathbf M$\), View-Matrix \($\mathbf V$\), Projection-Matrix \($\mathbf P$\) und einen Vertex \($\mathbf v$\) gilt ja dann bei dir: Ausgabekoordinaten sind \($(\mathbf{PV})\mathbf{Mv}$\). Dabei liegt \($(\mathbf{PV})$\) als eine Matrix vor.

Die Rotation in der Model-Matrix kannst du ohne Probleme auf Identität setzen. Wenn du weißt, wie die View-Matrix aussieht, kannst du dir einen „View-Matrix-Rotations-Eliminator“ \($\mathbf X$\) basteln, welcher in die Model-Matrix gestopft werden kann: \($\mathbf P(\mathbf{VX}) \mathbf{Mv} = (\mathbf{PV})(\mathbf{XM}) \mathbf v$\).

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:49
von dot
Genau das wollt ich auch grad schreiben. Angenommen dass deine Matritzen nur Rotationen und Translationen beinhalten sollte es reichen den oberen 3x3 Teil der Weltmatrix mit dem transponierten oberen 3x3 Teil der Viewmatrix zu überschreiben wenn ich nicht grad verwirrt bin (was aber durchaus nicht selten vorkommt).

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:50
von Krishty
Richtig. Und genau da hakt es:
Krishty hat geschrieben:
Schrompf hat geschrieben:Du müsstest also quasi den Rotationsanteil der Model-View-Matrix nichten, ohne die Wirkung der Projection Matrix zu beeinflussen. Ich glaube aber, das geht mathematisch gar nicht, wenn Du nicht zumindest eine der beiden Matrizen einzeln da hast. Und wenn Du sie einzeln da hast, ist das Ganze eh ein NoBrainer.
Habe ich jetzt, kriege es aber trotzdem nicht hin. Wenn ich die View-Matrix transponiere und dann ihre ersten 3×3 Zeilen in die World-Matrix kopiere blickt mich das Objekt zwar immer an, aber seine Achsen sind vertauscht. Negiere ich die drei oder vier Werte in der Hauptdiagonalen, spielt es wieder völlig verrückt.
Achja: Die View Matrix invertiert die Y-Achse, weil irgendjemand so klug war, die komplette Programmlogik vertikal zu invertieren m[
:(

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:55
von dot
Ah sry überlesen. Wenn dann müsstest du eine Zeile negieren und nicht die Diagonalelemente würd ich mal sagen!? Wobei das imo eigentlich nicht notwendig sein dürfte... :?

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:57
von Krishty
Wenn ich die 3×3 ohne Negation übernehme und mit einer 180°-Rotation um die X-Achse multipliziere, klappt es. Sehr seltsam.

dot, du hast recht: Wenn ich die zweite Zeile negiere, haut es hin. Das ist fuckin' weird …

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 20:59
von dot
Krishty hat geschrieben:Wenn ich die 3×3 ohne Negation übernehme und mit einer 180°-Rotation um die X-Achse multipliziere, klappt es.
...was einer Negation der Zeilen 2 und 3 gleichkommt wenn mich nicht alles täuscht :P

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 21:03
von Krishty
Japp, genau.

Also, für’s Protokoll: Ich habe die ersten 3×3 Komponenten der Weltmatrix mit den ersten 3×3 Komponenten der transponierten View-Matrix überschrieben (damit die World-Matrix die Rotation durch die View-Matrix ausgleicht) und dann die zweite und dritte Zeile negiert. Warum ich diese Negation durchführen muss, erschließt sich mir zwar nicht im geringsten, aber ich bin sehr froh, dass es endlich funktioniert :)

Dankeschön, dass hier so schnell so viele hilfreiche Posts gepurzelt sind :)

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 21:06
von Schrompf
Krishty hat geschrieben:Ich mache nicht nur die Billboards/Sprites in Software, sondern die gesamte Welttransformation.
So hatte ich Dich verstanden. Aber warum? Warum machst Du etwa mühsam in Software, wenn die Graka das viel besser kann?

Re: (gelöst) Weltrotation rückgängig machen

Verfasst: 16.06.2011, 21:15
von Krishty
Die Programmlogik hängt dran. Das betrifft vor allem markante Punkte für die Interaktion der Daten mit dem Nutzer und Picking, aber u.a. hängt sogar die Entscheidung, was gerendert werden muss, davon ab, ob ausgewählte Dreiecke dem Betrachter zugewandt sind oder nicht.

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 21:25
von dot
Krishty hat geschrieben:Warum ich diese Negation durchführen muss, erschließt sich mir zwar nicht im geringsten [...]
Wenn ich nochmal drüber nachdenk isses logisch. Die ursprüngliche ViewMatrix hat die y-Achse negiert, d.h. effektiv ein -1 an Stelle 22. Wenn die Weltmatrix jetzt exakt die transponierte der Viewmatrix enthält kommen aber alles 1en raus, d.h. die Spiegelung verschwindet. Damit die y-Spiegelung erhalten bleibt muss die zweite Zeile von World die negierte der zweiten Spalte von View sein damit bei der Multiplikation -1 rauskommt. Ich postuliere daher jetzt mal dass die Negation der 3ten Zeile nicht notwendig bzw. sogar falsch ist und nur im Moment keinen Unterschied macht da dein Testsetup nur Quads enthält...

Re: Weltrotation rückgängig machen

Verfasst: 16.06.2011, 21:28
von Krishty
dot hat geschrieben:Ich postuliere daher jetzt mal dass die Negation der 3ten Zeile nicht notwendig bzw. sogar falsch ist und nur im Moment keinen Unterschied macht da dein Testsetup nur Quads enthält...
Japp. Ich hatte zwischenzeitlich sogar dauernd [4][4] invertiert, ohne es zu merken.