|
|
(7 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) |
Zeile 1: |
Zeile 1: |
− | {{Unvollständig}}
| + | =Billboards= |
| Ein Billboard zu rendern ist eine Methode eine 2D Grafik in eine 3D Szene einzufügen. Wenn man eine einfache 2D Grafik hat, so möchte man diese meistens nicht irgendwo als 2 Dimensionale Plakatwand in eine 3D Szene pflanzen. Stattdessen möchte man, das diese 2D Grafik ähnlich wie ein [[Sprite]] in 2D immer zum Betrachter schaut, jedoch dieses Sprite in eine 3D Szene mit Tiefe, Tiefentest, 3D-Position, eventuell Beleuchtung und dergleichen gezeichnet wird. | | Ein Billboard zu rendern ist eine Methode eine 2D Grafik in eine 3D Szene einzufügen. Wenn man eine einfache 2D Grafik hat, so möchte man diese meistens nicht irgendwo als 2 Dimensionale Plakatwand in eine 3D Szene pflanzen. Stattdessen möchte man, das diese 2D Grafik ähnlich wie ein [[Sprite]] in 2D immer zum Betrachter schaut, jedoch dieses Sprite in eine 3D Szene mit Tiefe, Tiefentest, 3D-Position, eventuell Beleuchtung und dergleichen gezeichnet wird. |
| | | |
− | =Allgemeine Probleme= | + | ==Allgemeine Probleme== |
| Jede Billboard-Art hat eine Gemeinsamkeit: alle zielen darauf ab die Rotation (oder Teile der Rotation) der Szene rückgängig zu machen um das [[Primitive|Rechteck]] komfortabel (wie in 2D) zeichnen zu können. Jedoch soll im Gegensatz zur Ausrichtung des [[Primitive|Rechtecks]] die Position in der 3D-Szene sehr wohl von der Rotation der Szene abhängig sein. Um beides zu erreichen, können unterschiedliche Techniken mit Vor- und natürlich auch Nachteilen verwendet werden. Diese sollen hier vorgestellt werden. | | Jede Billboard-Art hat eine Gemeinsamkeit: alle zielen darauf ab die Rotation (oder Teile der Rotation) der Szene rückgängig zu machen um das [[Primitive|Rechteck]] komfortabel (wie in 2D) zeichnen zu können. Jedoch soll im Gegensatz zur Ausrichtung des [[Primitive|Rechtecks]] die Position in der 3D-Szene sehr wohl von der Rotation der Szene abhängig sein. Um beides zu erreichen, können unterschiedliche Techniken mit Vor- und natürlich auch Nachteilen verwendet werden. Diese sollen hier vorgestellt werden. |
| | | |
− | =Spherische Billboards= | + | ==Billboard Typen== |
− | Bei spherischen Billboards geht es darum, ein [[Primitive|Rechteck]] (meist ein Quadrat) immer zum Betrachter auszurichten, egal ob er von oben, unten, vorne oder von wo auch immer auf dieses [[Primitive|Rechteck]] blickt. Die Haupt-Anwendungsgebiete sind:
| + | Neben ein paar Sonderfällen gibt es hauptsächlich [[sphärisches Billboard|spährische]] (auch als World-aligned Billboards bekannt) und [[zylindrisches Billboard|zylindrische Billboards]] (auch Screen-aligned Billboards genannt). |
− | *[[Partikelsysteme]]
| |
− | *Illusion von Objekten mit der Form einer Kugel (Himmelskörper, Billiardkugeln, ...)
| |
− | *Können bei der Baumdarstellung für die Blätterbüschel verwendet werden
| |
| | | |
− | ==Mittels Matrixmanipulation==
| + | Ein solcher Sonderfall kann zum Beispiel die Darstellung eines [[Blitz]]es sein. |
− | Die Matrixmanipulation ist die einfacheste Form, jedoch für große Mengen von Billboards eher ungeeignet, da es mehr Aufwand bedeutet. Es gibt jedoch einen Spezialfall, bei dem diese Methode um einiges schneller sein kann als alle anderen Methoden. Man nehme an bei dem Billboard handelt es sich nicht um ein einfaches [[Primitive|Rechteck]] sondern (aus welchen Gründen auch immer) um ein recht komplexes Objekt mit 100erten Punken welches man immer zum Betrachter ausrichten möchte. Bei allen anderen Methoden ist eine Software-Transformation der Punkte in der ein oder anderen Form notwendig. Bei dieser Methode hingegen können die statischen Vertexdaten 1:1 an OpenGL geschickt werden. Aber nun zur Theorie:
| |
− | | |
− | Betrachten wir vorest die [[Matrix]] etwas genauer:
| |
− | {|
| |
− | | r || r || r || p
| |
− | |-
| |
− | | r || r || r || p
| |
− | |-
| |
− | | r || r || r || p
| |
− | |-
| |
− | | 0 || 0 || 0 || 1
| |
− | |}
| |
− | *r ... Rotationsmatrix
| |
− | *p ... Position
| |
− | Wenn die Rotationsmatrix der Identitäts-[[Matrix]] entspricht, so können wir das [[Primitve|Rechteck]] wie in 2D behandeln. Bleibt noch die Frage der Position. Wenn die Modelview Matrix dem lokalen Koordinatensystem des Billboards entspricht (sodass die Billboardposition (0|0|0) ist), so spielt die Rotationsmatrix bei der Position keine Rolle mehr. Denn
| |
− | {|
| |
− | | 0 || || r || r || r || p || || p
| |
− | |-
| |
− | | 0 || * || r || r || r || p || = || p
| |
− | |-
| |
− | | 0 || || r || r || r || p || || p
| |
− | |-
| |
− | | 1 || || 0 || 0 || 0 || 1 || || 1
| |
− | |}
| |
− | Da jedoch eher selten mehrere Billboards an der selben Position sein sollen, muss für jedes Billboard erneut die Matrix erstellt werden. Das setzen der Position muss hier über eine [[glTranslate|Translation]] erfolgen, also:
| |
− | [[glVertex]]( 10, 20, 30 ); <=> [[glTranslate]]( 10, 20, 30 ); [[glVertex]]( 0, 0, 0 );
| |
− | Dadurch lässt sich folgender Pseudocode für das Zeichnen von Billboards mit dieser Methode ableiten:
| |
− | Für jedes Billboard:
| |
− | [[glPushMatrix]]()
| |
− | [[glTranslate]]( BillboardPos.x, BillboardPos.y, BillboardPos.z )
| |
− | [[glGet]]( GL_MODELVIEW_MATRIX, Matrix )
| |
− | Setze Rotationsteil von Matrix auf Identitätsmatrix
| |
− | [[glLoadMatrix]]( Matrix )
| |
− | [[glVertex|glVertex2]]( + 1, + 1 )
| |
− | [[glVertex|glVertex2]]( - 1, + 1 )
| |
− | [[glVertex|glVertex2]]( - 1, - 1 )
| |
− | [[glVertex|glVertex2]]( + 1, - 1 )
| |
− | [[glPopMatrix]]()
| |
− | Da hier für jedes Billboard erneut die Matrix berechnet werden muss, ist diese Methode sehr aufwändig für eine große Anzahl von Billboards. Jedoch ist diese Methode verhältnismäßig einfach zu verstehen. Die [[glScale|Skalierung]] der Matrix wird hier verworfen und müsste nach dem setzen der Billboard-[[Matrix]] erneut erfolgen.
| |
− | | |
− | ==Mittels Softwaretransformation==
| |
− | Die Softwaretransformation ist ebenfalls eine eher einfach zu verstehende Methode. Obwohl sie bereits um einiges schneller als die Matrixmanipulation ist, ist sie dennoch nicht die schnellste Methode.
| |
− | Wie in der vorigen Methode können wir wenn die Rotationsmatrix der Identitäts-[[Matrix]] entspricht, das [[Primitve|Rechteck]] wie in 2D behandeln. Bleibt wiederum das Problem mit der Position. Dieses wird in dieser Methode so gelöst, das wir die Arbeit von OpenGL übernehmen, und die Billboardposition manuell (in Software) mit der Modelview [[Matrix]] multiplizieren. Dadurch kann die Modelview [[Matrix]] von OpenGL auf die Identitäts-[[Matrix]] gesetzt werden (was ein einfaches Zeichnen des Billboards ermöglicht) und wir können dennoch die richtige Position eines Billboards bestimmen. Im Unterschied zur vorigen Methode, wird hier nicht nur der Rotationsteil der [[Matrix]] auf die Identitätsmatrix gesetzt, sondern die gesamte Matrix. Und zwar weil wir ja auch die Position des Betrachters (also die Position der ursprünglichen Modelview [[Matrix]]) in die berechnete Position mit einfließen lassen.
| |
− | In Pseudocode sieht das etwa so aus:
| |
− | [[glPushMatrix]]() | |
− | [[glGet]]( GL_MODELVIEW_MATRIX, Matrix )
| |
− | [[glLoadIdentity]]()
| |
− | Für jedes Billboard:
| |
− | BPos = Billboard_Position * Matrix
| |
− | [[glVertex]]( BPos.x + 1, BPos.y + 1, BPos.z )
| |
− | [[glVertex]]( BPos.x - 1, BPos.y + 1, BPos.z )
| |
− | [[glVertex]]( BPos.x - 1, BPos.y - 1, BPos.z )
| |
− | [[glVertex]]( BPos.x + 1, BPos.y - 1, BPos.z )
| |
− | [[glPopMatrix]]()
| |
− | Dies erfordert also für jedes gezeichnete Billboard eine Multiplikation eines Vektors mit einer [[Matrix]] in Software. Wie in der ersten Methode wird auch hier die [[glScale|Skalierung]] der Matrix bei der Größe des Billboards nicht beachtet, die Position des Billboards wird allerdings auch für [[glScale|skalierte]] [[Matrix|Matrizen]] korrekt berechnet.
| |
− | | |
− | ==Mit Right- und Up- Vektor==
| |
− | Um das ganze etwas zu beschleunigen, kann man sich auch Right- und Up-Vektor arbeiten, die die aktuelle Rotation der Szene rückgängig machen, und statt einer einfachen 2D-Darstellung des [[Primitive|Rechtecks]] diese beiden Vektor zum spannen des [[Primitive|Rechtecks]] verwenden. Das herausfinden dieser beiden Vektoren erfordert eine noch detailiertere Betrachtung der Modelview [[Matrix]]. Üblicherweise ist der Rotationsteil der Modelview [[Matrix]] orthogonal. Bei einer orthogonalen [[Matrix]] ist die inverse [[Matrix]] gleich der transponierten [[Matrix]]. Unter dieser Annahmen können wir die Rotationsmatrix weiter aufteilen:
| |
− | {|
| |
− | | r || u || v || p
| |
− | |-
| |
− | | r || u || v || p
| |
− | |-
| |
− | | r || u || v || p
| |
− | |-
| |
− | | 0 || 0 || 0 || 1
| |
− | |}
| |
− | *r ... Right-(Rechts-)Vektor
| |
− | *u ... Up-(Nach oben-)Vektor
| |
− | *v ... View-(Blickrichtungs-)Vektor
| |
− | *p ... Position
| |
− | Und obwohl die Mathematik dahinter vielleicht nicht ganz trivial ist, ist die Praxis dafür umso einfacher. Was jetzt noch fehlt ist das aufspannen des [[Primitive|Rechtecks]] mit dem so heraus gefundenen Right- und Up- Vektor. In Pseudocode sieht das so aus:
| |
− | [[glGet]]( GL_MODELVIEW_MATRIX, Matrix )
| |
− | Right = Vektor( Matrix[0], Matrix[4], Matrix[8] )
| |
− | Up = Vektor( Matrix[1], Matrix[5], Matrix[9] )
| |
− | Für jedes Billboard:
| |
− | [[glVertex]]( BPos.x + Right.x + Up.x, BPos.y + Right.y + Up.y, BPos.y + Right.y + Up.y )
| |
− | [[glVertex]]( BPos.x - Right.x + Up.x, BPos.y - Right.y + Up.y, BPos.y - Right.y + Up.y )
| |
− | [[glVertex]]( BPos.x - Right.x - Up.x, BPos.y - Right.y - Up.y, BPos.y - Right.y - Up.y )
| |
− | [[glVertex]]( BPos.x + Right.x - Up.x, BPos.y + Right.y - Up.y, BPos.y + Right.y - Up.y )
| |
− | Wobei BPos wiederum die Billboard-Position ist.
| |
− | Wie unschwer zu erkennen wird hier (gleich wie bei der vorigen Methode) nur einmal je Frame die Modelview [[Matrix]] benötigt. Hier fällt jedoch zusätzlich noch die [[Matrix]]multiplikation weg und da die Modelview [[Matrix]] nicht verändert wird, müssen auch nicht alle Billboards hintereinander gezeichnet werden, sondern können zu einem beliebigen Zeitpunkt (sofern es sich noch um die selbe Modelview [[Matrix]] handelt) an OpenGL gesendet werden. Der einzige Aufwand besteht in ein paar Additionen die sogar noch auf nur 12 (statt 24) Additionen reduziert werden können, wenn man sich die Right- und Up- Vektoren in 4 Vektoren für den 1., 2., 3. und 4. Punkt vorberechnet. In Software ist dies üblicherweise die schnellste Methode Billboards darzustellen.
| |
− | | |
− | ==Mittels Point-Sprites (Hardware)==
| |
− | Mit der [[NV_Point_Sprite]]-Extension hat NVidia vor einigen Jahren sog. Point-Sprites eingeführt, die, vor allem für die Darstellung von Partikelsystemen, Vorteile bringen. Während man ansonsten für jeden Partikel vier Eckpunkte (wenn als Quad gerendert) über den Bus schieben musste und jeden Partikel auch noch am Bildschirm ausrichten musste, muss man unter Nutzung dieses Hardwarefeatures nur noch einen einzigen Punkt (Zentrum des Billboards) an die Grafikkarte senden und der Rest wird von der Hardware übernommen. Also müssen dann sehr viel weniger Daten (1 Eckpunkt statt 4, Texturkoordinaten müssen gar keine gesendet werden, das wird automatisch erledigt) über den Bus geschoben werden und es muss auch nicht mehr manuell am Bildschirm ausgerichtet werden. Vor kurzem hat diese Funktionalität übrigens Einzug in den GL-Kern gefunden, unter der Bezeichnung [[ARB_point_sprite]] ([http://oss.sgi.com/projects/ogl-sample/registry/ARB/point_sprite.txt Original Spezifikation (engl.)].
| |
− | Natürlich eignet sich diese Methode primär nur für Partikelsysteme, denn hier wird automatisch an allen drei Achsen ausgerichtet, was besonders bei größeren Billboards (z.B. Bäumen, bei Gräsern kann man das machen) unerwünscht ist.
| |
− | | |
− | ==Mittels Vertexprogramm==
| |
− | | |
− | =Zylindrische Billboards=
| |
Ein Billboard zu rendern ist eine Methode eine 2D Grafik in eine 3D Szene einzufügen. Wenn man eine einfache 2D Grafik hat, so möchte man diese meistens nicht irgendwo als 2 Dimensionale Plakatwand in eine 3D Szene pflanzen. Stattdessen möchte man, das diese 2D Grafik ähnlich wie ein Sprite in 2D immer zum Betrachter schaut, jedoch dieses Sprite in eine 3D Szene mit Tiefe, Tiefentest, 3D-Position, eventuell Beleuchtung und dergleichen gezeichnet wird.
Jede Billboard-Art hat eine Gemeinsamkeit: alle zielen darauf ab die Rotation (oder Teile der Rotation) der Szene rückgängig zu machen um das Rechteck komfortabel (wie in 2D) zeichnen zu können. Jedoch soll im Gegensatz zur Ausrichtung des Rechtecks die Position in der 3D-Szene sehr wohl von der Rotation der Szene abhängig sein. Um beides zu erreichen, können unterschiedliche Techniken mit Vor- und natürlich auch Nachteilen verwendet werden. Diese sollen hier vorgestellt werden.