DirectX Drehung um einen Vector



  • Stimmt, jetzt hab ichs auch erst geraft. Alle deine Drehungen finden im lokalen Kamerasystem statt, also wie Dot gesagt hat, erst x dann y (oder umgekehrt). Schwieriger wirds wenn die Z Orientierung, aufrecht lassen wie willst (so wie es der Mensch es gewohnt ist). Dann Drehst du Z (halb-)global und Y lokal, fertsch.
    (lokal bedeutet multipliokation von links, global kann man so nicht sagen, hängt davon ab was zuvor geschehen ist).



  • Ob von links oder rechts für lokale Transformationen hängt von der API ab, die hier noch nicht weiter genannt wurde, oder?
    Für DirectX ist Multiplikation von links "lokal"
    Für OpenGL ist Multiplikation von rechts "lokal"



  • Es häng von den jeweils verwendeten Konventionen ab, weder OpenGL noch Direct3D machen da irgendwelche Vorgaben...



  • Zu Zeiten von Fixed-Function-Pipelines hatte man aber keine Wahl darüber, von welcher Seite sie auf der GPU multipliziert wurden? Hat sich das inzwischen dahingegen geändert, dass man sich halt in den Shadern aussucht, wie multipliziert wird?
    Ich musste mich für Direct2D die letzten Tage wieder daran gewöhnen, von links zu multiplizieren, halte von rechts für natürlicher.



  • Decimad schrieb:

    Zu Zeiten von Fixed-Function-Pipelines hatte man aber keine Wahl darüber, von welcher Seite sie auf der GPU multipliziert wurden?

    Die Zeiten von Fixed-Function-Pipelines sind aber schon seit mindestens 10 Jahren vorbei... 😉

    Decimad schrieb:

    Hat sich das inzwischen dahingegen geändert, dass man sich halt in den Shadern aussucht, wie multipliziert wird?

    exakt 😉



  • Macht das die Multiplikationseinheiten nicht "komplizierter" und langsamer? Immerhin muss ja dann eine Vertausch-Einheit zwischen Vektor, Matrix und Recheneinheit bemüht werden, was die Latenz für alle solche Produkte steigert, oder nicht? Oder werden für diesen doch überaus oft ausgeführten Rechenschritt keine spezialisierten Vorschalteinheiten vor die Floating-Point-Einheiten geschaltet? Versuche mir gerade vorszustellen, wie das technisch realisiert ist. Für sowas oft genutztes wird doch wahrscheinlich kein flexibles N*N-Programm auf den Shader-Einheiten ausgeführt...



  • Der GPU ist das völlig egal, der Shadercompiler generiert einfach anderen Code. Abgesehen davon basieren moderne GPUs sowieso nicht mehr auf Vektoreinheiten (NVIDIA schon seit der GeForce 8 nimmer, ATI hat's afaik erst vor kurzem aufgegeben)... 😉

    Aber ja, je nachdem welche Konvention und welches Memory Layout man verwendet, sind verschiedene Multiplikationsreihenfolgen potentiell unterschiedlich effizient...



  • Naja, ich mein, wenn ein Vektor-Matrix-Produkt keine speziellen Schaltkreise mehr verwendet, sondern ebene über ein Programm ausgeführt wird, dann ist es der GPU natürlich egal. Aber ich kann mir nicht vorstellen, dass man damit nur halbwegs an eine spezialisierte Recheneinheit rankommt Oo

    Also ich meine natürlich auch unter dem Gesichtspunkt, dass diese spezielle Steuereinheit etwas Platz wegnimmt für eine unspezialisierte weitere generelle Recheneinheit. Schließlich werden solche Produkte doch wirklich wirklich häufig eingesetzt.



  • Für Vektor Matrix Produkte gab es afaik nie spezielle Schaltkreise, zumindest nicht in Zeiten von Shadern. Ältere Hardware war noch vektorbasiert, da wurden Matrixprodukte dann über Vektoroperationen realisiert, heutzutage arbeiten GPUs aber skalar.

    Für die Hardware ist das alles völlig uninteressant. Der Shadercompiler generiert je nach Speicherlayout der Matritzen eben entsprechenden Code, das ist alles...



  • Jau, wie das inner Api umgesetzt ist, ist mir völlig schnuppe. Wenn die api xT*AT (alles klar Zeilenvektoren, wasn müll :D) als Transformation implementiert, gerne. Aber inner Mathematik isses nun mal Ax=y eine Trafo innen andres System. Folgerichtig ist "links der Matrix das Zielsystem und rechts der Matrix das Ursprungssystem".



  • Jap, mathematisch gesehen ist das die einzig richtige Variante.



  • Das verblüfft mich jetzt. CPUs sind doch auf skalarer Ebene absolut unschlagbar ausgelegt und werden für solche Operationen mit jeder SSE- oder AVX-Generation dennoch immer vektorieller ausgelegt (scheinbar ist hier also der Einsatz von Chipfläche für SSE also effizienter, als eine menge kleiner General-Purpose-Einheiten vorzusehen). Wie kann dann eine GPU schneller für solche Operationen sein, wenn sie sie programmweise skalar ausführt?

    Das muss ja offenbar ein Tradeoff zwischen Chipfläche/Durchsatz sein, bei dem ich irgendwie noch nicht alle Faktoren überblicke.



  • Es ist genau das, ein anderer Tradeoff. CPUs sind auf minimale Latenz ausgelegt, GPUs auf maximalen Durchsatz. Auf einer CPU ist ein sehr großer Teil des Chips nur Cache, auf einer GPU besteht der Großteil des Chips aus Recheneinheiten. Der Trick, dessen GPUs sich nun bedienen, ist Latency Hiding. Die CPU versucht Speicherlatenz durch Caches zu vermeiden, die GPU wartet einfach nicht, sondern switched zu einem anderen Thread. Eine CPU ist gut darin, einige wenige Threads mit komplizierten Kontrollflüssen möglichst schnell auszuführen. Eine GPU ist gut darin, möglichst viele Threads mit unkomplizierten Kontrollflüssen gleichzeitig auszuführen. Um eine GPU sinnvoll zu nutzen, braucht es also Anwendungen, die abertausende Threads gleichzeitig beschäftigen können...



  • ScottZhang schrieb:

    (lokal bedeutet multipliokation von links, global kann man so nicht sagen, hängt davon ab was zuvor geschehen ist).

    Da hatte ich halt folgendes Bild vor augen: (BA)x. (B von links multipliziert). B ist aber ganz offensichtlich nicht "lokal" für das x, das ich abbilden möchte. In meiner Logik halte ich die Matrizen solange getrennt von dem Vektor, bis die resultierende Transformation dann wirklich ausgeführt werden soll, und dann wird's von rechts nach links ja immer "globaler". Andererseits ist B natürlich "lokal" für Ax. Ich weiß natürlich nicht, ob wir in dieser Hinsicht irgendwie voneinander abweichen. Aber am Ende meinen wir offenbar das gleiche 😃



  • Hey 🙂

    Ich war etwas länger abgetaucht denn wir hatten viel zu programmieren.
    Jein. Also für das Problem das wir hatten hat es nicht gereicht 2 einfache Matrizen nach Schema Y dann X zu multiplizieren.
    Aber dann haben wir gemerkt das wir einen Denkfehler hatten, denn die von uns ausgerechnete Version war nicht mit der intuitiven Steuerung durch einen Joystick vereinbar.
    Dafür mussten wir dann letztendlich nur X Y und Z Matrizen der entsprechenden Joystick Achsen auf multiplizieren. (Der Joystick hat neben X und Y noch eine axiale Drehung mit Z)

    Ich kannte schlichtweg die Funktion D3DXMatrixRotationAxis() nicht. ziemlich doof^^ Danke daher 🙂

    Hier ist ein kleines Video von dem Dndresultat. Die Steuerung ist nur so hackelig weil ich es mit der Tastatur mache [W A S D Q E X Y J K I und L...] Mit Joystick sieht es natürlich cooler aus. Aber der ist an unsere Platinen gebunden, und die hab ich nicht zuhause^^
    www.youtube.com/watch?v=hj8bP1SYKW0



  • Cool! 👍 Mich begeistern solche Teile immer, genau wie Delta-Roboter oder all die anderen Parallelkinematiken. Viel Freude, das Teil dann auch real zu basteln!



  • ja sind grade dabei 🙂
    Die Aluteile lassen teilweise ganz schön auf sich warten... aber Platinen haben wir schon gefräst und mit den entsprechenden BTMs, ATMEGAs etc bestückt.


Anmelden zum Antworten