Home
WebGL Api Spickzettel
WebGL Sicherheit
Tutorial
0 : WebGL Browser
1 : Das erste Dreieck
2 : 3D-Mathematik
3 : Farbe
4 : Animation
5 : Interaktion I
6 : Texturen
7 : Beleuchtung I
8 : Interaktion II
Links
WebGL Beispiele
WebGL Frameworks
ext. WebGL Tutorials
Kontakt / Impressum
webgl ([ät)] peter-strohm Punkt de
|
2 3D und 2D und die Mathematik
>>>> Direkt zum Beispiel <<<<
In Kapitel 1 sind wir direkt in den Quellcode eingestiegen, haben die grobe
Struktur des Beispiels erarbeitet und kleine Veränderungen darin ausprobiert.
Jezt werden wir tiefer in die Mathematik einsteigen. Man könnte vielleicht -
ausgehend vom ersten Beispiel oder einer anderen WebGL-Datei - direkt weitere
"Gimmicks" wie Farben, Animation, Mausbehandlung etc. irgendwie
hineinbasteln, aber hier soll auch das Verständnis der Grundlagen nicht
vernachlässigt werden.
Wir arbeiten in WebGL im 3-dimensionalen Raum, i.A. in karthesischen
Koordinaten. X, Y und Z-Achse stehen senkrecht aufeinander und bilden ein
Rechtssystem. Die Kamera (das virtuelle Auge) befindet sich bei
WebGL-Projekten (vorläufig) im Ursprung (x=0, y=0, z=0) und blickt in Richtung
der negativen z-Achse.
Bild 2.1 : Kartesisches Koordinatensystem
Ich verwende in diesem Tutorial die Farbzuordnung x:rot, y:gelb/orange, z:grün, weil
jeder der schon einmal eine Verkehrsampel gesehen hat, sich diese Reihenfolge
merken kann.
In diesem 3D-Raum können 3D-Punkte (genannt Vertices, singular Vertex) zunächst
einmal mit beliebigen Koordinatenwerten angegeben werden. Wo z.B. der Punkt
P=(1/1/-1) liegt sollte dir klar sein. Falls nicht, empfehle ich ein Buch über
räumliche Geometrie oder zur Not auch die 11.Klasse einer gymnasialen
Oberstufe.
In diesem Kapitel werde ich auf die mathematischen Hintergründe eingehen und
den Weg vom 3D-Punkt im Raum zum 2-dimensionalen, aber räumlich wirkenden Bild
erläutern.
2.1 Positionierung von
3D-Objekten - Die Modelview-Matrix
Im Beispiel aus Kapitel 1 haben wir ein dafür gesorgt, dass das Dreieck im
Blickfeld des Betrachters liegt in dem wir die Z-Koordinaten aller 3 Punkte
auf auf negative Werte (-1.0) gesetzt haben. Dieses Vorgehen wird sehr schnell
sehr aufwändig, wenn man mit komplexeren Objekten arbeiten möchte. Es würde
bedeuten, dass wir die Koordinaten von jedem einzelnen Punkt eines
Alien-Raumschiffes (oder was immer sonst unsere 3D-Programmierung am Ende
ergibt) im Koordinatensystem der Kamera angeben müssten. Die praktikablere und
üblichere Vorgehensweise ist, Objekt in ihrem eigenen Koordinatensystem zu
definieren und anschließend mit Hilfe von ein wenig Mathematik zu verschieben
und zu drehen, so dass sie in der gewünschten Position vor der Kamera
landen.
Das Stichwort hierzu lautet "Modelview-Matrix". Die Modelview-Matrix
beinhaltet die Translation (Verschiebung) und Rotation(Drehung) zu einem
bestimmten 3D-Objekt.
Die Verbindung von Translation und Rotation in einer einzigen Matrix scheint
zunächst nicht selbstverständlich zu sein. Für die Verschiebung eines Punktes
im Raum benutzt man eine einfache Vektoraddition:
$\vec{v}_{verschoben} = \vec{v}_{original} + \vec{v}_{verschiebung}$ (2.1)
bzw. in ausgeschriebener Form:
$\left(\begin{array}{c} v_{neuX} \\ v_{neuY} \\ v_{neuZ} \end{array}\right) = \left(\begin{array}{c} v_{altX} \\ v_{altY} \\ v_{altZ} \end{array}\right) + \left(\begin{array}{c} v_{verschiebungX} \\ v_{verschiebungY} \\ v_{verschiebungZ} \end{array}\right)$ (2.2)
Die Rotation von Vertices ist nicht ganz so anschaulich. Da es hier ja
eigentlich um WebGL und weniger um Geometrie gehen soll, verweise ich auf die
Erläuterungen zur
Rotationsmatrix in Wikipedia.
Die Rotationsmatrix, um einen 3D-Punkt um die Z-Achse zu rotieren, sieht so aus:
$ \left(\begin{array}{c} v_{neuX} \\ v_{neuY} \\ v_{neuZ} \end{array}\right) =
\left(\begin{array}{rrr} \cos(\alpha) & -sin(\alpha) & 0 \\ sin(\alpha) & cos(\alpha) & 0 \\ 0 & 0 & 1 \end{array}\right)\left(\begin{array}{c} v_{altX} \\ v_{altY} \\ v_{altZ} \end{array}\right)
$ (2.3)
wobei Alpha der Drehwinkel ist.
Um also ein Objekt um seine eigene Achse zu drehen und anschließend zu
verschieben, müssten die beiden Operationen (Multiplikation mit der
Rotationsmatrix und Vektoraddition nacheinander ausgeführt werden). Die
Reihenfolge ist dabei NICHT egal.
Da diese Operationen in der 3D-Grafikverarbeitung sehr häufig gemeinsam
auftreten, wendet man einen kleinen Trick an um die Berechnungsvorschrift zu
verkürzen:
Man erweitert die Vektoren um ein 4. Element, das den Wert 1 hat und konvertiert
die Vektoraddition in eine 4x4 - Translationsmatrix:
$ \left(\begin{array}{c} v_{neuX} \\ v_{neuY} \\ v_{neuZ} \\ 1 \end{array}\right) =
\left(\begin{array}{rrrr} 1 & 0 & 0 & v_{VerschiebungX} \\ 0 & 1 & 0 & v_{VerschiebungY} \\ 0 & 0 & 1 & v_{VerschiebungZ} \\ 0 & 0 & 0 & 1 \end{array}\right)\left(\begin{array}{c} v_{altX} \\ v_{altY} \\ v_{altZ} \\ 1 \end{array}\right)
$ (2.4)
Wenn du schon einmal Vektoren und Matrizzen multipliziert hast, siehst du
schnell, dass Gleichungen (2.2) und (2.4) das Gleiche aussagen.
Die Rotationsmatrix wird nach dem gleichen Prinzip erweitert (ich beschränke
mich hier zunächst auf die Rotation um die Z-Achse, mit Y und X oder einer
beliebigen Rotationsachse sieht es aber im Prinzip sehr ähnlch aus.)
$ \left(\begin{array}{c} v_{neuX} \\ v_{neuY} \\ v_{neuZ} \\ 1 \end{array}\right) =
\left(\begin{array}{rrrr} \cos(\alpha) & -sin(\alpha) & 0 & 0 \\ sin(\alpha) & cos(\alpha) & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right)\left(\begin{array}{c} v_{altX} \\ v_{altY} \\ v_{altZ} \\ 1 \end{array}\right)
$ (2.5)
Mit diesen Vorüberlegungen kannst du alle (affinen) Transformation im Raum
durch Multiplikation des Raumpunktes mit entspechenden Matrizzen
beschreiben.
Für die Anwendung bedeutet das, dass du nur die richtigen Matrizzen in der
richtigen Reihenfolge miteinander multiplizieren musst, um ein Objekt wie
gewünscht in der WebGL-3D-Szene zu platzieren
Beispielsweise möchtest du in einem WebGL-basierten 3D-Weltraumspiel vor der
Kamera eine Alienraumschiff mit einem stieläugigen Alien in der Pilotenkanzel
darstellen.
Um die Position und Orientierung des Alienauges zu bestimmen müsstest du "nur"
folgende Matrizzenmultiplikation durchführen:
$ \vec{v}_{Alienauge vor der Kamera} =$ | $M_{Position des Raumschiffes}$ $\cdot M_{Rotation des Raumschiffes}$ $\cdot M_{Position des Aliens im Raumschiff}$ $\cdot M_{Rotation des Stielauges am Alien}$ $\cdot \vec{v}_{0Alienauge}$ | (2.6)
|
Neben dieser eher formellen Vereinheitlichung von Translation und Rotation
ergibt sich noch ein weiterer Aspekt:
In der Praxis werden die Matrizzen die mehrfach gemeinsam auftreten (z.B.
Rotation und Translation unseres Alien-Raumschiffes) miteinander multipliziert
und das Ergebnis auf den Vektor angewendet. Damit kann enorm viel
Rechenaufwand eingespart werden und die Übersichtlichkeit von 3D-Szenen
(Scenegraphs) wird gegeben.
Solch eine Matrix, die eigentlich das Ergebnis von mehreren
Multiplikationen und Translationen ist wird Modelview-Matrix genannt.
D.h. man wird in (gutem) WebGL-Quellcode keine Konstrukte wie (2.6) finden,
sondern eher
$\vec{v}_{Alienauge vor Kamera} = M_{Modelview Alienauge} \cdot \vec{v}_{0 Alienauge}$ (2.7)
Die Modelview-Matrix dient dazu, 3D-Objekt in der virtuellen Welt zu
positionieren.
2.2 Fern und nah - Die Projektionsmatrix
Du hast in Kapitel 2.1 gelernt, wie 3D-Punkte (bzw. Objekte) im virtuellen
3D-Raum positioniert werden. Leider ist das nur der erste Schritt um eine
räumlich wirkende 3D-Szene auf den Bildschirm zu bringen.
Im Bereich der 3D-Computergrafik lautet eine essentielle Frage:
"Wenn ein Punkt im Raum an den Koordinatenwerten (1/1/-1) liegt, an welchen
Koordinaten muss er dann am 2D-Bildschirm erscheinen ?"
Die Zahlenwerte (1/1/-1) sind natürich unbedeutend und beliebig.
Das Zauberwort um diese Frage zu beantworten heißt Projektion. Gesucht
ist der (mathematische) Zusammenhang zwischen den 3D-Koordinaten der
zweidimensionalen Abbildung auf dem Bildschirm.
Ich werde hier die zwei am weitesten verbreiteten Arten von Projektionen in
der 3D-Grafik vorstellen:
die orthografische und die perspektivische
Projektion.
Und weil die räumliche Wirkung eines einzelnen Punktes eher bescheiden ist,
dient ab sofort ein Würfel als Anschauungsobjekt:
Bild 2.2 : Projektionsarten: links orthografisch, rechts perspektivisch
Wie du in Bild 2.2 erkennen kannst wirken beide Würfel in gewisser Weise
räumlich. Der Unterschied ist, dass in der perspektivischen Projektion Objekte
um so kleiner dargestellt werden, je weiter sie vom Betrachter entfernt sind.
Das entspricht unserer Erfahrung aus der Realität (da wo der Pizzabote
herkommt).
Die orthografische Projektion findet v.A. in technischen Darstellungen, z.B.
Architektenzeichnungen eines Hauses Verwendung. Dort ist es nützlich, zu
erkennen, dass das Haus vorne und hinten gleich hoch ist, obwohl es räumlich
dargestellt ist.
Für Freunde der Malerei kann man es auch so erklären, dass bei der
orthografischen Darstellung kein Fluchtpunkt vorhanden ist. Parallele
Linien, die in die Tiefe des Bildes laufen, bleiben parallel.
Und noch einen weiteren Vorteil hat die orthografische Projektion: Sie ist
einfacher zu berechnen!
Du ahnst es wohl schon: für schöne, realistische Darstellung wird man
perspektivische Darstellungen verwenden und sich nicht mit orthografischer
Projektion zufrieden geben.
Weil der Weg zur perspektivischen Projektion ohnehin über die orthografische
Projektion führt, fangen wir mit letzterer an:
2.2.1 Die orthografische Projektion
Wir wollen unseren Punkt (1/1/-1) orthografisch auf die Zeichnungfläche
(Canvas) aus Kapitel 1 projezieren. Wir wissen, dass die Zeichnungsfläche 500
Pixel hoch und 500 Pixel breit ist.
Wir können noch frei definieren, wie breit und hoch der Blick in die 3D-Welt
sein soll. Wie viele Einheiten (z.B.Meter) der 3D-Welt sollen in den 500
Pixeln untergebracht werden?
Ich entscheide spontan, dass die Begrenzung bei -2 und +2 liegt (in Höhe und
Breite gleich), damit können Objekte bis 4 Einheiten Höhe und Breite
vollständig dargestellt werden.
Das folgende Bild soll zur Veranschaulichung des Sichtbereichs
(Field of View (fov)) dienen:
Bild 2.3 : Sichtfeld / Field of View bei orthografischer Projektion
Wie oben bereits erwähnt, ist die Blickrichtung der virtuellen Kamera in
Richtung der negativen z-Achse. Der sichtbare Bereich beginnt mit der Ebene
z-nah. Diese begrenzt, wie nah Objekte in der virtuellen Welt der Kamera
kommen dürfen um noch dargestellt zu werden. In meinen Beispielen verwende ich
i.d.R. hier einen Wert von 0.1 Längeneinheiten. Die hinten begrenzende Ebene
ist mit Z FERN benannt und gibt analog an, bis zu welchem Abstand zur
virtuellen Kamera Objekte gezeichnet werden. Für diesen verwenden wir bis auf
weiteres 100.0 Längeneinheiten.
Das spezielle an der Orthografischen Projektion ist, dass die begrenzenden
Flächen bei Z NAH und Z FERN gleich groß sind. Es gibt keine Aufweitung des
Sichtfeldes in der Ferne.
Das heißt im Umkehrschluss, das es für die x/y-Position eines 3D-Punktes auf
der 2D-Leinwand keine Rolle spielt, wie groß oder klein der Z-Wert ist. Ganz
ignorieren darf man den Z-Wert allerdings dennoch nicht, weil bei mehreren
Objekten die vorderen (kleiner negativer Z-Wert) die hinteren (großer
negativer Z-Wert) überdecken sollen. Hier kommt die Z-Order (auf
deutsche etwa Tiefen-Reihenfolge) ins Spiel.
WebGL stellt in der Zeichnungsfläche alles dar, das einen z-Wert zwischen -1
und +1 hat und beginnt mit den größten Werten, so dass das Problem der
Überdeckung zunächst korrekt dargestellt wird. Diese Begrenzung auf -1 und +1
gilt auch für die x- und y-Achsen. Wir müssen uns also nicht um die Skalierung
auf die 500px breite Zeichenfläche kümmern. Das erledigt WebGL für uns.
Es ist unsere Aufgabe als Programmierer, die Z-Koordinaten der 3D-Modellwelt
in diese Skala zwischen -1 und +1 zu transformieren.
Die folgende Matrix erledigt genau das. Ich empfehle dir, mit Papier und
Bleistift mal ein paar Beispielwerte einzusetzten und die Z-Werte zu
überprüfen
$\left(\begin{array}{rrrr} \frac{2}{rechts-links} & 0 & 0 & 0 \\ 0 & \frac{2}{oben-unten} & 0 & 0 \\ 0 & 0 & \frac{-2}{z_{fern}-z_{nah}} & \frac{-\left(z_{fern}+z_{nah}\right)}{z_{fern}-z_{nah}} \\ 0 & 0 & 0 & 1 \end{array}\right)$ (2.8)
bzw. mit dem erwähnten Zahlenbeispiel
$\left(\begin{array}{rrrr} \frac{2}{4} & 0 & 0 & 0 \\ 0 & \frac{2}{4} & 0 & 0 \\ 0 & 0 & \frac{-2}{99.9} & \frac{-100.1}{99.9} \\ 0 & 0 & 0 & 1 \end{array}\right)$
Für Sichtfelder, die nicht symmetrisch zum Ursprung sind (du erinnerst dich,
ich habe "links" und "rechts" auf -2 und +2 gesetzt, entsprechend "oben" und
"unten") sieht die Verallgemeinerung von (2.8) so aus:
$\left(\begin{array}{rrrr} \frac{2}{rechts-links} & 0 & 0 & \frac{-\left(links+rechts\right)}{rechts-links} \\ 0 & \frac{2}{oben-unten} & 0 & \frac{-\left(unten+oben\right)}{oben-unten} \\ 0 & 0 & \frac{2}{z_{fern}-z_{nah}} & \frac{-\left(z_{fern}+z_{nah}\right)}{z_{fern}-z_{nah}} \\ 0 & 0 & 0 & 1 \end{array}\right)$ (2.9)
Achtung! Diese und die weiteren Matrizzen werden im Javascript-Quellcode
spaltenweise angegegen, daher sieht es im Quellcode aus als seien sie
transponiert (um die Hauptdiagonale gespiegelt).
Ich verzichte auf eine wortreiche Erklärung, wie man zu den Elementen der
Matrix kommt. Es sind einfache Geometrie- und Dreisatz-Beziehungen. Wenn du dir
selbst eine Skizze davon machst, ist es bald erkennbar.
2.2.2 Die perspektivische Projektion
Zunächst wieder eine grafische Darstellung, bei der dir der Unterschied zu
Bild 2.3 auffallen sollte:
Bild 2.4 : Sichtbereich (Field of View) mit einer Perspektivmatrix
Wie schon bei der Orthografischen Projektion wird der Sichtbereich durch die
Ebenen bei Z NAH und Z FERN begrenzt. Hier hat die (quadratische) Fläche bei
Z-Fern jedoch eine wesentlich größere Ausdehnung als die Fläche bei Z-NAH. Der
Sichtbereich wird durch einen Pyramidenstumpf begrenzt. In der
englischsprachingen Literatur findet man diesen unter dem Begriff
View-Frustrum
Neben den Zahlenwerten für Z NAH und Z FERN wird der Pyramidenstumpf durch
seine Öffnungswinkel in x- und y-Richtung eindeutig beschrieben. In der Praxis
gibt man jedoch nur den vertikalen (y) Öffnungswinkel und das Seitenverhältnis
Breite/Höhe an, woraus sich der andere Öffnungswinkel ergibt.
Wir erinnern uns nochmal an die Ausgangsfragestellung:
"Wenn ein Punkt im Raum an den Koordinatenwerten (x/y/z) liegt, an welchen
Koordinaten muss er dann am 2D-Bildschirm erscheinen ?"
Offenbar kommt jetzt im Vergleich mit der Orthografischen Projektion noch der
Öffnungswinkel und eine Abhängigkeit von z mit ins Spiel.
Die Perspektivmatrix, die wir später im Beispiel auf Raumpunkte anwenden um
sie perspektivisch realistisch auf unserer 2D-Zeichenfläche darzustellen sie
wie folgt aus:
$\left(\begin{array}{rrrr} \frac{Seitenverhältnis}{\tan \left(Öffnungswinkel\right)} & 0 & 0 & 0 \\ 0 & \frac{1}{\tan \left(Öffnungswinkel\right)} & 0 & 0 \\ 0 & 0 & \frac{z_{fern}+z_{nah}}{z_{fern}-z_{nah}} & \frac{2\cdot z_{fern} \cdot z_{nah}}{z_{nah}-z_{fern}} \\ 0 & 0 & -1 & 0 \end{array}\right)$ (2.10)
Der tan(α) in der Matrix sorgt dafür, dass sich das Sichtfeld mit
zunehmendem Abstand zur Kamera aufweitet. Die letzte Zeile [0 0 -1 0] sorgt
dafür, dass im 4. Element des Ergebnisvektors nicht wie bisher eine 1 stehen
muss, sondern der negative Z-Werte des Eingangsvektors. Da das Ergebnis dieser
Multiplikation im Vertexshader berechnet wird, sorgt WebGL dafür, dass
letztendlich wieder die 1 an der vierten Stelle des Vektors steht, indem alle
Elemente des Ergebnisvektors durch das 4. dividiert werden (-z). Diese
Division ist entscheidend für die Perspektivische Projektion: 1/z sorgt dafür,
dass Objekt im Nahbereich immer größer werden bis sie schließlich das gesamte
Sichtfeld einnehmen und im Fernbereich immer kleiner werden ohne völlig zu
verschwinden. Weiterhin gilt natürlich das Z NAH und Z FERN (die sog.
Clipping-Ebenen) die absolute Grenze der Darstellung angeben. Davor und
dahinter geht garnichts.
2.3 Ein Beispiel zur Anwendung
der Modelview- und Projektionsmatrizzen
Beispiel (juhu! endlich!)
Das Beispiel zu Kapitel zwei greift in 3 Aspekte schon etwas auf kommende
Kapitel vor:
- Es wird statt dem flachen Dreieck aus Kapitel 1 ein räumlicher Würfel
verwendet. Dieser ist nichts anderes als insgesamt 12 einzelne Dreiecke und
somit keine Zauberei.
- Es verwendet Beleuchtung (sonst wäre der räumliche Effekt praktisch nicht
zu sehen). Alles was dir im Quellcode unter dem Stichwort "lighting" und
"normals" begegnet gehört dazu und braucht dich erstmal nicht zu
interessieren.
- Tastatureingaben werden benutzt um den Würfel zu drehen.
Das klingt sicherlich spannend und ich kann dich nicht daran hindern, dir
diese Funktionalität im Quellcode anzuschauen, aber in diesem Kapitel möchte
ich deine Aufmerksamkeit auf die Verwendung der Modelview- und
Projektionsmatrizzen lenken:
Die Projektionsmatrizzen werden abhängig von der Userauswahl der Radiobuttons
"orthografische Projektion" bzw. "perspektivische Projektion" angelegt.
(jeweils spaltenweise d.h. scheinbar transponiert):
orthografisch:
138 | pMatrix = new Float32Array([
| 139 | 2/(rechts-links), 0 , 0 , 0,
| 140 | 0, 2/(oben-unten), 0 , 0,
| 141 | 0, 0 , -2/(zFern-zNah), 0,
| 142 | -(rechts+links)/(rechts-links), -(oben+unten)/(oben-unten) , -(zFern+zNah)/(zFern-zNah) , 1
| 143 | ]);
|
perspektivisch:
150 | pMatrix = new Float32Array([
| 151 | aspektVerhaeltnis/Math.tan(sfOew), 0, 0, 0,
| 152 | 0, 1/Math.tan(sfOew), 0, 0,
| 153 | 0, 0, (zNah+zFern)/(zNah-zFern), -1,
| 154 | 0, 0, 2*zNah*zFern/(zNah-zFern), 0]);
| 155 |
|
Unmittelbar danach wird die Modelview-Matrix erstellt. Wie du vielleicht bei
der Definition der Raumpunkte des Würfels (Zeilen 21-56) gesehen hast, ist
der Würfel in "seinem eigenen" Koordinatensystem beschrieben. Die Mitte des
Würfels liegt in (0/0/0).
158 | mvMatrix = new mat4.create();
| 159 |
| 160 | mat4.identity(mvMatrix);
| 161 | //Modell um 3 Einheiten auf der z-Achse verschieben:
| 162 | mat4.translate(mvMatrix,[0,0,-3.0]);
| 163 | //Model rotieren:
| 164 | mat4.rotateX(mvMatrix,g_xRot* Math.PI / 180.0);
| 165 | mat4.rotateY(mvMatrix,g_yRot* Math.PI / 180.0);
| 166 | mat4.rotateZ(mvMatrix,g_zRot* Math.PI / 180.0);
|
Bei der Vektor- und Matrizzen Rechnung machen wir häufig Gebrauch von den
Funktionen aus Brandon Jones gl-matrix.js
Bibliothek. Wenn du dich also fragst, woher die Funktionen mat4.translate
oder mat4.identity kommen, solltest du mal einen Blick in das API
von gl-matrix.js werfen.
Wir legen nun zuerst eine Einheitsmatrix (4x4) an um diese in Zeile 162 mit
Hilfe von gl-matrix.js in eine Translationsmatrix zu überführen.
Anschließend rotieren wir diese Matrix nacheinander um x, y und z mit den
Rotationswinkeln xRot, yRot und zRot die durch die Tastatureingaben (w-a-s-d)
veränderlich sind.
Du siehst hier, dass die Modelview-Matrix des Würfels insgesamt 4
Transformationen beinhaltet (eine Verschiebung und 3 Drehungen).
Ein paar Zeilen später im Quellcode werden mit getUniformLocation(..) und
uniformMatrix4fv(..) die gerade erstellten Matrizzen an die Shader übergeben.
Ein kleiner Sprung in den Quellcode des Vertex-Shaders:
Dort passiert in Zeile 246 genau das was dieses Kapitel beschrieben
hat:
Der Ortsvektor jedes einzelnen Raumpunktes wird zuerst mit der Modelview- und
anschließen mit der Projektionsmatrix multipliziert.
246 | gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); \n\
|
Hinweis: Mit Blick auf die Performance ist es oft sinnvoll, die Multiplikation
von Modelview- und Projektionsmatrix nicht im Shader, sondern vorab einmalig auf der
CPU auszuführen und dann als "uniform" an den Shader zu übergeben. Voraussetzung ist
natürlich, dass beide Matrizzen konstant sind.
Das Ergebnis wird der WebGL-vordefinierten Variablen gl_Position
übergeben und geht seinen Gang durch die Grafikpipeline auf den Bildschirm.
Kapitel 2 ist damit abgeschlossen. Es sollte dir einen Einblick in die Mathematik
zur 3D-Grafik mit WebGL bieten. Man kann sicherlich auf der einen Seite noch
beliebig viel tiefer in diese theoretischen Aspekte eintauchen, auf der
anderen Seite kann man auch WebGL-Programmieren ohne sich mit dem wie und
warum der Matrizenrechnung auseinander zu setzen.
In den nächsten Kapiteln wird es wieder praktischer zur Sache gehen. (Farben,
Animation, Texturen....) Es bleibt spannend!
Thanks to Giles Thomas and his project
LearningWebGL.com
|