Die Matrix

Die Matrix ist ein Science-Fiction Film aus dem Jahre 1999 in dem Keanu Reaves die Hauptrolle spielt. Vollkommen richtig, aber auch vollkommen am Thema vorbei. In diesem Artikel geht es nicht um Filme, sondern um die mathematische Matrix. Ok, mathematische Grundlagen… Das klingt deutlich langweiliger als ein Science-Fiction-Blockbuster und das ist es sicherlich auch. Ich versuche diesen trockenen Stoff hier möglichst so rüberzubringen, daß es schnell und schmerzlos geht und einigermaßen interessant bleibt. Wie immer möchte ich mich dabei nicht in den Tiefen der Mathematik verirren und auch nicht in endlos auschweifenden Erklärungen verlieren, sondern das vermitteln, was man zur täglichen Arbeit in der Spieleentwicklung benötigt.

Dieser Artikel ist ein vorbereitender Artikel für den vierten Teil meiner Shader 101 Reihe. Ich erachte dieses Thema jedoch als so wichtig, daß ich mich entschlossen habe, es in einem eigenen Beitrag zu behandeln. Das Themengebiet findet schliesslich nicht nur Anwendung in der Erzeugung einer Landschaft sondern bei jedem 3D-Projekt.

Laut Wikipedia versteht man unter einer Matrix (Plural: Matrizen) eine rechteckige Anordnung, also eine Tabelle von Elementen, mit denen man in bestimmter Weise rechnen kann. Dieser Wikipedia-Artikel beschreibt dann übrigens auch, wie so eine Matrix aufgebaut ist, wie mit ihnen gerechnet wird und noch einiges mehr. Aber genau das ist Wissen, was wir eben in vielen Fällen nicht unbedingt benötigen. XNA stellt uns eigentlich alles zur Verfügung, was wir zum arbeiten mit Matrizen benötigen und macht daher dieses Wissen optional. Schaden kann es sicherlich nicht, aber meistens kommt man auch ganz gut ohne zurecht, obwohl es einige spezielle Themenbereiche gibt, in denen man sich damit gut auskennen sollte.

Ich möchte mich auch in diesem Artikel ausschließlich auf die XNA-Matrizen beschränken, deren Dokumentation wie immer in der MSDN zu finden ist. XNA verwendet jedenfalls eine 4×4 Matrix, also mit 16 Elementen, die „row major“ angelegt ist. Dies bedeutet, daß die Elemente zeilenweise gelesen werden, also wie folgt:

01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16

Der Vollständigkeit halber ist hier zu erwähnen, daß es auch „column major“ Matrizen gibt, deren Elemente spaltenweise angeordnet sind.

Anwendungsgebiete

Matrizen sind eines der Grundkonzepte in der 3D-Grafik, aber auch in der 2D-Grafik nützlich. Fast alles was hier geschrieben wird, kann also auch im 2D-Raum angewendet werden.

Eine Matrix ermöglich es uns einen Vektor zu transformieren, also zu verschieben, zu skalieren, also in der Größe zu verändern und zu rotieren, also um den Nullpunkt herum zu drehen. Diese Operationen können (müssen aber nicht) alle in einer Matrix vorhanden sein und in einem Arbeitsschritt auf einen Vektor angewendet werden. Dies erfolgt mit den Transform-Methoden von Vector3 und Vector2.

Damit haben wir auch schon das erste, wichtige Anwendungsgebiet der Matrix genannt: Die Transformation. Wie schon bemerkt, fassen wir darunter die Verschiebung, die Skalierung und die Rotation zusammen. Dies wird zum Beispiel benötigt, um ein Objekt im 3D-Raum zu positionieren (die sogenannte World-Matrix) oder um eine virtuelle Kamera zu erzeugen (die sogenannte View-Matrix).

Das zweite wichtige Anwendungsgebiet einer Matrix ist die Projektion, auf die ich hier aber nicht detailliert eingehen will. Ich werde später ein paar kurze Worte dazu verlieren, aber da man die Projektion zwar immer benötigt, wird dort einfach eine Matrix mit einer Methode erzeugt und einfach gesetzt. Wie das intern abläuft ist dabei in der Regel eher uninteressant, weshalb ich in der Beschreibung dieses Themas etwas schludern werde.

Kombination von Matrizen

Natürlich ist es auch möglich, mehrere Matrizen zu einer neuen zusammenzufassen. Dies erfolgt bei einer Matrix nicht durch eine Addition, sondern durch eine Multiplikation. Dabei ist ein wichtiger Punkt zu beachten: Die Multiplikation von Matrizen ist nicht kommutativ. Dies bedeutet schlicht und einfach, daß die Reihenfolge der Multiplikation beachtet werden muß und wichtig ist.

Dabei gilt folgende Regel:

Skalierungs-Matrix * Rotations-Matrix * Translations-Matrix

Diese Reihenfolge sollte man verinnerlichen und sich gut merken, da dies häufig benötigt wird. Wird eine der Matrizen nicht benötigt, so kann man sie einfach auslassen.

Eine kleine Besonderheit gibt es noch. Die Rotation bezieht sich immer auf den Nullpunkt des Koordinatensystems, was oft nicht gewünscht ist. In der Regel möchte man um einen bestimmten Punkt rotieren. Diesen Punkt nennt man Origin, also den Ursprung. Um den Ursprung für die Rotation festzulegen wird dieser einfach als erster Parameter in der „Multiplikations-Kette“ angegeben:

Origin-Matrix * Skalierungs-Matrix * Rotations-Matrix * Translations-Matrix

Vorteile von Matrizen

Nachdem wir nun einen Einblick in die Anwendungsgebiete und Funktionsweise von Matrizen bekommen haben, stellt sich dem ein oder anderen vielleicht die Frage, was denn überhaupt der Vorteil einer Matrix ist und warum diese überhaupt verwendet werden sollte. Man kann doch alle diese Dinge auch relativ einfach ohne lösen. Dies ist einfach zu erklären. Ich möchte an dieser Stelle wieder nicht exakt auf die mathematischen Hintergründe eingehen und verweise dafür auf den Matrix und Quaternion-FAQ, aus dem ich hier aber ein paar Resultate zitieren möchte.

Arbeitet man ohne eine Matrix, so benötigt man folgende Operationen um eine Skalierung, Transformation und Rotation durchzuführen:

Vorbereitung: 6 trigonometrische Funktionen und 6 Zuweisungs-Operationen
Pro Vertex: 12 Zuweisungen, 12 Multiplikationen und 9 Additionen

Mit einer Matrix sieht es wie folgt aus:

Vorbereitung: 6 trigonometrische Funktionen, 18 Zuweisungs-Operationen, 12 Multiplikationen und 6 Subtraktionen
Pro Vertex: 3 Zuweisungen, 9 Multiplikationen und 6 Additionen

Wie man dabei sieht sind die Vorbereitungskosten, also das erzeugen der Matrix bzw. das vorberechnen einiger Werte bei der Matrix deutlich höher. Dafür sind aber die späteren Kosten je Vertex deutlich geringer. Es werden 9 Zuweisungen, 3 Multiplikationen und 3 Additionen pro Vertex gespart. Wenn man sich nun eine Spielfigur mit 10000 Vertices vorstellt, dann erkennt man sehr deutlich das riesige Potential einer Matrix und kann sich die Zeitersparnis durch deren Verwendung sicherlich vorstellen. Ein modernes Spiel verwendet übrigens durchaus mal 200.000 Vertices, die teilweise mehrfach transformiert werden müssen.

Übrigens noch ein Wort der Fairness: Wenn man diese Zahlen gegenüberstellt, dann merkt man, daß sich die Matrix unterm Strich erst ab 4 Vertices lohnt.

Erzeugung von Matrizen

Normalerweise ist das Erzeugen von Matrizen ein rechenintensiver Vorgang, für den man einen guten mathematischen Hintergrund haben muss. Glücklicherweise liefert uns das XNA-Framework eine ganze Reihe von Methoden, die uns diese Aufgabe stark erleichtern. Diese sind in der MSDN ausführlich erklärt. Die wichtigsten sind dabei sicherlich: CreateScale, CreateTranslation und CreateRotation.

Sehr wichtig ist auch noch die Invert-Methode. Diese dreht eine Matrix praktisch um und erzeugt so eine invertierte Matrix. Dies ist hilfreich um die Wirkung einer Matrix wieder aufzuheben. Wenden wir also eine Matrix auf einen Vektor an, gefolgt von der invertierten Matrix so befindet sich der Vektor danach wieder an der Position, an der er sich befunden hat, bevor er durch die Matrizen transformiert wurde. Wird eine Matrix mit der zugehörigen Matrix multipliziert, so entsteht eine sogenannte Identity-Matrix.

Die Identity-Matrix ist praktisch eine Null-Matrix. Diese hat keinerlei Effekt auf einen Vektor und macht schlicht und einfach nichts. Erzeugen können wir diese über die statische Eigenschaft Identity der Matrix-Struktur.

Die Projektion

Zuvor hatte ich ja bereits geschrieben, daß es auch eine Projektionsmatrix gibt. Die Projektionsmatrix („Projection matrix“) ist dafür zuständig, daß 3D-Koordinaten in den 2D-Raum überführt werden. Dies ist notwendig, da unser Monitor schliesslich eine 2D-Fläche ist und kein 3D-Raum. Wir müssen also eine 3D-Koordinate so in zwei Dimensionen umrechnen, daß ein Tiefeneindruck entsteht.

Glücklicherweise liefert uns hier XNA auch ein paar nette Hilfsfunktionen, nämlich Matrix.CreatePerspectiveFieldOfView, Matrix.CreatePerspective und Matrix.CreatePerspectiveOffCenter. Die wichtigste ist dabei die erste Methode. Dies ist die Perspektivische Projektion.

Die zweite, wichtige Möglichkeit zur Projektion ist die sogenannte Orthographische Projektion. Dabei entsteht kein Tiefeneindruck, da Objekte die weiter hinten sind nicht kleiner wirken. Auch dafür liefert XNA die passen Methoden zur Erzeugung: Matrix.CreateOrthographic und Matrix.CreateOrthographicOffCenter.

Fazit

In diesem Artikel habe ich versucht die wichtigsten Informationen über Matrizen zusammenzufassen. Ich habe ohne auf die mathematischen Hintergründe detailliert einzugehen beschrieben, wozu eine Matrix verwendet wird, was ihre Vorteile sind und was bei der Verwendung zu beachten ist. Ich habe eine Reihe von Links und Querverweisen geliefert, die es problemlos ermöglichen, dieses Thema sehr detailliert in Eigenregie auszuarbeiten. Oft sind diese Hintergrundinformationen aber nicht notwendig, da XNA für die meisten Anwendungsfälle vorgefertigte Methoden und Eigenschaften liefert.

Ich hoffe, daß ich mit diesem Grundlagen-Artikel ein wenig Licht ins Dunkel bringen konnte und werde diesen in anderen Artikeln referenzieren, um diese nicht mit wiederkehrenden Informationen zu überfluten.

Sollte etwas unverständlich sein, Themengebiete noch nicht berücksichtigt worden sein oder wenn du einfach nur ein Lob, Dank oder Kritik aussprechen möchtes, dann verwende dafür einfach die Kommentarfunktion unter diesem Artikel.

Advertisements

Veröffentlicht am 17.06.2011 in Grundlagen, Mini-Tutorial, XNA und mit , , , , , , getaggt. Setze ein Lesezeichen auf den Permalink. 5 Kommentare.

  1. Hi,

    guter Artikel.
    Da du hier World-View-Projection-Matrix erwähnst, habe ich mir gedacht, ein Artikel über die Grafikpipeline wäre sicher nicht schlecht für die Leser. Ich habe mal einen Artikel geschrieben, den könntest du haben, wenn du willst.
    Leider habe ich im Moment keine Zeit zum Artikel schreiben und deswegen habe ich meine Homepage noch nirgendwo verlinkt, da zuwenig Info darauf ist. Bevor mein Artikel dort verstaubt, dachte ich, du könntest ihn eventuell gebrauchen 😉

    • Danke für das Lob und das Angebot. Klar, ich nehme gerne auch Gast-Artikel an 🙂 Ich möchte die aber natürlich vorher lesen und ggfls. etwas editieren. Dafür gibts aber natürlich Credits und ein Mitspracherecht 😉

      Wenn du Lust hast, dann schick mir den Artikel einfach per EMail und dann schauen wir mal, was daraus wird.

  2. Ja, habe ich bekommen, habe aber bisher nur mal quergelesen, da ich etwas busy war… Ich melde mich die Tage…

  1. Pingback: Terrain 101: Transformationen « "Mit ohne Haare"

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: