Portal

Aus DGL Wiki
Version vom 23. September 2005, 09:20 Uhr von Flo (Diskussion | Beiträge) (Der Kategorie Anleitung zugeordnet)

Wechseln zu: Navigation, Suche

Portale orientieren sich sehr stark an der menschlichen Sichtweise von Indoor-Levels. Es geht darum, ein Level in mehrere Bereiche einzuteilen und diese Bereiche über (möglichst kleine) Portale zu verbinden. Der typische Platz für ein Portal ist somit ein Durchgang, eine Tür, ein Fenster oder ähnliches. Jeder Raum erhält nun eine Liste von Portalen zu anderen Räumen. Wenn man weiß in welchem Raum man sich befindet (dies kann beispielsweise über einen BSP-Baum herausgefunden werden), so muss man nur die Sichtbarkeit der einzelnen Portale prüfen um zu wissen welche Räume (möglicherweise) sichtbar sind. Die Sichtbarkeitsabfrage von Portalen geschieht üblicherweise über Backface Culling und Viewfrustum-Culling. Nachdem ihr diesen Artikel gelesen habt, werdet ihr die kleinen Miniräume und Fahrstühle in Spielen wie Doom3 mit anderen Augen sehen.

Sichtbarkeitsabfragen

Sichtbarkeitsabfragen sind eines der Haupt-Anwendungsgebiete von Portalen. Die Geometrie eines Portales ist üblicherweise durch ein auf einer Ebene liegendes Viereck und den Normalvektor dieser Ebene definiert. Natürlich ist es auch möglich ein Portal über ein beliebiges Polygon (jedoch ein Polygon wo alle Punkte auf einer Ebene sind) zu definieren. Um die daraus folgenden Berechnungen nicht unnötig komplex zu machen, wird üblicherweise jedoch zumindest ein konvexes Polygon verwendet. Zusätzlich beinhaltet ein Portal noch die Information zwischen welchen Räumen es sich befindet.

Einfache Sichtbarkeitsabfragen

Mit verschiedensten Algorithmen zur Sichtbarkeitsabfrage kann bestimmt werden ob ein Portal sichtbar ist oder nicht.

Backface Culling

Mit Hilfe des Normalvektors kann ein sehr effizientes Backface Culling durchgeführt werden durch die Formel welche den Winkel zwischen zwei Vektoren bestimmt: Winkel = ArcCos( VektorA * VektorB ) Wobei "*" ein Punktprodukt der beiden Vektoren ist. Der Arcus Cosinus hat die Eigenschaft:

  • ArcCos( 0 ) => Winkel = 90 Grad
  • ArcCos( > 0 ) => Winkel < 90 Grad
  • ArcCos( < 0 ) => Winkel > 90 Grad

Somit braucht nur geprüft werden ob das Punktprodukt zwischen Normalvektor und Blickrichtung kleiner 0 ist. Ist dies der Fall, so ist dieses Portal nicht sichtbar.

Viewfrustum Culling

Die Viewfrustum besteht aus 6 Ebenen. Das Viereck befindet sich mit sicherheit ausserhalb der Viewfrustum, wenn alle 4 Punkte des Vierecks ausserhalb der selben Ebene liegen. Es ist auch möglich, dass beispielsweise 2 Punkte links ausserhalb der Viewfrustum und 2 Punkte rechts ausserhalb der Viewfrustum liegen. In diesem Fall kann man nicht sicher sein, dass das Viereck nicht teilweise innterhalb der Viewfrustum liegt, denn dies ist auch der Fall wenn man komplett durch das Portal hindurch blickt ohne dessen Ränder zu sehen. Somit muss die Einschränkung der selben Ebene beachtet werden um sicher gehen zu können.

Hardware Occlusion Culling

Mit neueren Grafikkarten ist es möglich Objekte auf ihre Sichtbarkeit zu prüfen. Die einfache Geometrie (ein Viereck) eines Portales bietet sich hier natürlich gut an. Dafür sollte aber natürlich darauf geachtet werden, dass vor der Sichtbarkeitsabfrage der gesamte Raum mit all seinen Objekten gezeichnet wird, da ansonnsten das Occlusion Culling eher sinnlos ist.
Siehe auch GL_EXT_occlusion_test.

Probleme

Wenn ein Portal nicht sichtbar ist, so muss der dahinter liegende Raum nicht gezeichnet werden. Wenn ein Portal sichtbar ist, so ist noch das ein oder andere zu beachten:

Eingrenzung der Viewfrustum

Durch ein Portal kann man die Viewfrustum eingrenzen, also die Viewfrustum verkleinern wodurch nachfolgende Portale und Objekte mit einer höheren Wahrscheinlichkeit als nicht sichtbar erkannt werden. Ist das Portal komplett innerhalb der Viewfrustum, so erhält man wiederum eine 6-Seitige Viewfrustum. Wenn die Viewfrustum das Portal jedoch schneidet, so kann die neue Viewfrustum unnötig komplex werden. Im Schlimmsten Fall kommen 4 neue Ebenen zur eingegrenzten Viewfrustum hinzu. Hier sollte demnach eine Einschränkung getroffen werden welche Ebenen sinnvoll und welche eher weniger sinnvoll für das weitere Viewfrustum Culling sind.

Doppelte Sichtbarkeit eines Raumes

Wenn man beispielsweise einen Raum mit zwei Fenstern nach draussen hat, so ist es möglich, dass beide Fenster sichtbar sind. Hier ist es natürlich ratsam den Aussenraum nur einmal zu zeichnen und nicht doppelt. Dafür ist es jedoch notwendig, die Eingrenzung der Viewfrustum (falls dies verwendet wird) entsprechend anzupassen. Im Endeffekt hat man hier zwei Möglichkeiten:

  1. Man führt die Sichtbarkeitsabfragen mit zwei eingegrenzten Viewfrustums durch. Beim ersten mal werden alle Objekte auf Sichtbarkeit geprüft, beim zweiten mal nur noch die, welche beim ersten mal nicht sichtbar waren. Dadurch prüft man jedoch einen großteil der Objekte umsonnst doppelt auf ihre Sichtbarkeit. Sinnvoll ist dies natürlich wenn die Fenster in unterschiedliche Richtungen zeigen (zB eines nach Norden, eines nach Osten) weniger sinnvoll jedoch wenn beide in die selbe Richtung zeigen.
  2. Man führt die Sichtbarkeitsabfrage mit einer Viewfrustum durch die nicht eingegrenzt wurde, oder die beide Fenster mit einschließt. Dadurch muss zwar jedes Objekt des Aussenraumes nur einmal geprüft werden, jedoch werden auch einige Objekte als Sichtbar erkannt die von dem dazwischen liegenden Mauerstück verdeckt sind.

Eine allgemeine, ideale Lösung wäre hier sehr Aufwändig zum berechnen, somit ist es sinnvoll dem Grafiker die Wahl zu überlassen welche Methode verwendet wird.

Weitere Anwendungsmöglichkeiten

Level of Detail

Ähnlich zu Imposters können bei weiter entfernten Portalen die Räume dahinter in eine Textur gerendert werden und die darauffolgenden Frames wird der gesamte Raum (oder die Räume) dahinter nur noch mit dieser Textur dargestellt. Wenn sich der Blickwinkel stärker ändert, so wird aus dem neuen Blinkwinkel die Textur neu gerendert und um Popping zu verhindern über einen bestimmten Zeitraum mit der anderen überblendet. Natürlich ist es dafür notwendig, dass sich in diesem Raum (diesen Räumen) keine sichtbaren, dynamischen (also bewegten) Objekte befinden, da ansonnsten die Textur zu oft neu gerendert werden müsste.

Spiegel, Übergänge und Magie

Dadurch, dass ein Portal die Information beinhaltet zwischen welchen Räumen es liegt, ist es natürlich auch möglich Räume zu verbinden die physikalisch an komplett unterschiedlichen Orten liegen, oder auch einen Raum mit sich selbst. Wenn sich zwei Räume an komplett unterschiedlichen Orten befinden, so ist es jedoch notwendig eine Transformation zum Portal hinzu zu fügen, und zwar sowohl eine Translation als auch eine Rotation. Dadurch ist es ohne Probleme möglich, einen 10 Meter langen Tunnel zu machen, der 10 Kilometer weiter entfernt endet. Dies kann sehr praktisch sein wenn man in einem Welteditor nicht eine gesamte Höhle in die Welt setzen möchte, sondern nur die Ein- und Ausgänge einer Höhle. Da es natürlich auch möglich ist ein solches Portal zu einem weit entfernten Ort auch mitten in den Raum zu stellen, eignen sich Portale auch sehr gut für die Darstellung von "magischen" Transportmöglichkeiten und den flüssigen Übergang von einem Ort zum anderen. Ein netter Nebeneffekt des ganzen ist, das man auch sehr einfach Spiegel machen kann, indem man einfach die Transformation abhängig von der Betrachterposition macht, bzw. die Betrachterposition und den Blickwinkel am Portal spiegelt. Für die Portale "mitten im Raum" und auch die Spiegel ist es jedoch meistens ratsam den Bereich in den gezeichnet wird mit dem Stencil-Puffer einzugrenzen, um den Tiefenpuffer in den anderen Bereichen nicht zu zerstören.