Areaportals, Hints und Occluder: was welches Sichtproblem löst
Areaportals, Hint/Skip-Brushes und Occluder im Vergleich: wie jedes Werkzeug arbeitet, was es kostet, wann du es setzt und wie du es im Spiel prüfst.
Hint-Brushes, Areaportals und Occluder lösen drei verschiedene Sichtprobleme. Ein Hint ändert beim Kompilieren den Zuschnitt der Visleafs und kostet im Spiel nichts. Ein Areaportal beschneidet zur Laufzeit die Sicht auf eine Öffnung oder sperrt den Bereich dahinter ganz. Ein Occluder versteckt zur Laufzeit nur Models, die vollständig hinter einer Fläche liegen.
Drei Werkzeuge, zwei Zeitpunkte
VBSP zerlegt den Innenraum in Visleafs, und VVIS berechnet für jedes Leaf, welche anderen Leafs von dort aus sichtbar sein könnten (das PVS). Die Grundlagen stehen in GMod Map optimieren und VBSP, VVIS und VRAD erklärt. Die drei Werkzeuge greifen an unterschiedlichen Stellen ein:
- Hint und Skip wirken beim Compile. Du bestimmst, wo VBSP Leafs schneidet, und veränderst damit das Ergebnis von VVIS.
- Areaportals teilen die Map beim Compile in Areas, entscheiden aber erst im Spiel, was gezeichnet wird.
- Occluder arbeiten ausschließlich im Spiel.
VVIS berücksichtigt Areaportals nicht: In unserer Testmap standen zwei Räume trotz korrekt gesetzter Portale weiterhin gegenseitig im PVS. Im Spiel nimmt die Engine also zuerst das PVS, beschneidet es an den Areaportals und prüft zuletzt Models gegen Occluder.
Hint und Skip: den Leaf-Zuschnitt steuern
Ein Hint-Brush ist ein World-Brush, bei dem die Schnittfläche tools/toolshint trägt und alle übrigen Flächen tools/toolsskip. VBSP wählt seine Schnittebenen aus den Flächen der Brushes. Im VBSP-Code des Source SDK 2013 werden Skip-Flächen nie gewählt, und eine Ebene, die eine Hint-Fläche zerschneiden würde, wird gemieden, solange sie nicht selbst ein Hint ist.
Das klassische Beispiel ist ein Flur, der im rechten Winkel abknickt:
- Ohne Hint schneidet VBSP entlang einer der beiden Innenwände. Es entstehen zwei Leafs, die sich über ein Portal berühren. Vom Ende des einen Arms aus zeichnet die Engine auch das Ende des anderen.
- Setze einen keilförmigen Brush in die Ecke. Seine Hint-Fläche schneidet die Außenecke ab: Sie verläuft im 45-Grad-Winkel von Außenwand zu Außenwand und berührt dabei genau die Innenkante der Ecke.
- Der Hint trennt ein dreieckiges Stück von der Ecke ab, und jeder Arm behält ein eigenes Leaf. Die Leafs der beiden Arme berühren sich nur noch an der Innenkante und haben kein gemeinsames Portal mehr.
In unserem Test mit den Compilern von GMod stieg die Zahl dadurch von 2 Leafs und 1 Portal auf 4 Leafs und 3 Portale, weil VBSP das Eck-Dreieck entlang einer Innenwand noch einmal teilte. Die beiden Arm-Enden standen nicht mehr gegenseitig im PVS. In der Ecke selbst siehst du weiterhin beide Arme.
Jeder Hint-Schnitt erzeugt Leafs und Portale, die VVIS berechnen muss. Mehr dazu in VVIS dauert ewig.
Areaportals: Öffnungen beschneiden und schließen
Ein func_areaportal ist ein einzelner Brush mit tools/toolsareaportal, der eine Öffnung vollständig ausfüllt.
- Offen: Die Engine verengt die Sicht auf den Ausschnitt der Öffnung. Leafs außerhalb davon werden übersprungen, und jedes Entity im Bereich dahinter wird mit seiner Bounding Box gegen diesen Ausschnitt geprüft.
- Geschlossen: Der Bereich dahinter wird gar nicht gezeichnet, solange kein anderes offenes Portal hineinführt.
Die wichtigste Regel: Die beiden Seiten eines Portals müssen in verschiedenen Areas liegen. Jede Verbindung zwischen zwei Areas muss deshalb durch ein Portal oder durch World-Brushes verschlossen sein. func_detail, Displacements, Brush-Entities und Props dichten nicht ab. Mehr dazu in func_detail oder World-Brush.
Für Türen trägst du im Portal unter „Name of Linked Door“ den Namen der Tür ein und stellst „Initial State“ so ein, wie die Tür startet. Im Code des Source SDK 2013 öffnen func_door, func_door_rotating und prop_door_rotating jedes func_areaportal, das sie als verknüpfte Tür nennt, sobald die Tür aufgeht, und schließen es erst, wenn sie ganz zu ist. Mach den Portal-Brush laut Valve-Wiki dünner als die Tür, damit sie geschlossen sichtbar bleibt.
func_areaportalwindow schließt sich nach Entfernung statt per Tür. Zwischen „Fade Start Distance“ (Standard 128) und „Fade End Distance“ (Standard 512) blendet es das unter „Rendered Window“ eingetragene Brush-Entity ein und sperrt danach den Bereich. Mit einer Tür lässt es sich nicht verknüpfen: Es hat kein Feld dafür, und der Tür-Code im SDK sucht nur nach func_areaportal.
Einen Areaportal-Leak finden
Berührt ein Portal auf beiden Seiten dieselbe Area, meldet VBSP das so:
Processing areas...Wrote meinemap.lin
Areaportal leak ! File: meinemap.lin
Brush 88: areaportal brush doesn't touch two areas
VBSP bricht an dieser Stelle nicht ab. In unserem Test mit den Compilern von GMod schrieb es trotzdem die BSP und die Portal-Datei, und VVIS lief ohne Fehler durch. Die fertige BSP enthielt aber nur eine einzige Area und keine Areaportal-Daten, beide Räume lagen also in derselben Area. Wie das Spiel mit einer solchen Map umgeht, haben wir nicht getestet. Weil nichts anhält, geht die Meldung leicht unter. Mehr dazu in Compile-Log lesen.
- Lade die
.lin-Datei in Hammer überMap > Load Pointfile. In unserem Test führte die Linie von einer Seite des Portals durch die offene Verbindung zur anderen Seite. - Weißt du nicht, welches Portal gemeint ist, springst du mit
View > Go to Brush Numberzur Brush-ID aus der Meldung. - Suche entlang der Linie nach der Lücke: ein zweiter Durchgang ohne Portal, eine Wand aus
func_detailoder Displacements, oder ein Portal-Brush, der die Öffnung nicht ganz ausfüllt.
func_occluder: Models hinter einer Fläche verstecken
Ein func_occluder schneidet keine Leafs, muss nichts abdichten und kann frei im Raum stehen. Die Engine prüft in jedem Bild, ob die Bounding Box eines Models vollständig hinter der verdeckenden Fläche liegt, und zeichnet es dann nicht. Geprüft werden nur Models, also Props, NPCs und Spieler. World-Brushes und Displacements blendet ein Occluder nicht aus, und Brush-Entities nimmt der Client-Code des Source SDK 2013 von der Prüfung aus.
Du baust ihn als Brush im Inneren von etwas Blickdichtem, etwa einer Wand aus func_detail, einem Hügel aus Displacements oder einem Gebäude aus Props. Die verdeckenden Flächen bekommen tools/toolsoccluder, alle übrigen tools/toolsnodraw. Er wirkt nur aus der Richtung, aus der du auf eine Occluder-Fläche schaust.
Occluder sind laut Valve-Wiki pro Objekt teurer als offene Areaportals. Sie lohnen sich deshalb nur, wenn eine große Fläche viele Models verdeckt.
Vergleich: welches Werkzeug wofür
| Werkzeug | Blendet World-Geometrie aus | Blendet Props aus | Compile-Kosten | Laufzeit-Kosten | Typischer Einsatz |
|---|---|---|---|---|---|
| Hint und Skip | ja, ganze Leafs | ja, mit dem Leaf | mehr Leafs und Portale für VVIS | keine | Ecken in Fluren und Gängen |
| Areaportal | ja, außerhalb des Ausschnitts, geschlossen den ganzen Bereich | ja, einzeln per Bounding Box | gering, ein zusätzliches Leaf je Portal | für jedes sichtbare offene Portal | Türen, Fenster, Gebäudeeingänge |
| Occluder | nein | ja, wenn vollständig verdeckt | keine | für jeden Occluder und jedes geprüfte Model | freistehende Sichtblocker im offenen Gelände |
Daraus ergibt sich die Reihenfolge: zuerst World-Brushes als Sichtblocker, dann Hints, dann Areaportals an Engstellen mit viel Inhalt dahinter, und Occluder nur dort, wo keine Wand abdichten kann.
Im Spiel prüfen
Teste mit vollständig berechnetem VVIS. Die folgenden Befehle sind in der Engine von GMod vorhanden. Die ersten fünf sind dort cheat-geschützt und brauchen sv_cheats 1, r_occlusion nicht:
mat_wireframe 1
mat_leafvis 1
r_lockpvs 1
r_DrawPortals 1
r_portalsopenall 1
r_occlusion 0
mat_wireframe 1zeichnet alles Gerenderte als Drahtgitter, auch hinter Wänden.mat_leafvis 1zeigt das Leaf, in dem die Kamera steht, undr_lockpvs 1friert das PVS ein, damit du herumfliegen kannst. Damit kontrollierst du Hints.r_DrawPortals 1umrandet Areaportals, undr_portalsopenall 1zwingt alle Portale auf. Ändert sich das Drahtgitter beim Umschalten nicht, spart das Portal an dieser Stelle nichts.r_occlusion 0schaltet das Occlusion-System zum Vergleich ab.
Das Compile-Log dazu kannst du im Map Scanner einfügen, der in VBSP-, VVIS- und VRAD-Logs Ursachen und Folgefehler erkennt.
Häufige Fragen
Kann ich ein Areaportal mit einem Trigger steuern?
Ja. func_areaportal hat die Inputs Open, Close und Toggle. Das Portal hat aber nur einen Zustand für alle Spieler. Für Multiplayer empfiehlt das Valve-Wiki vor allem dauerhaft offene Portale, danach Portale an Türen und erst zuletzt per Trigger gesteuerte.
Wie viele Areaportals sind zu viele?
Eine feste Zahl gibt es nicht. Jedes sichtbare offene Portal kostet Rechenzeit, und wenn es zu wenig ausblendet, ist die Szene ohne Portal schneller. Jedes Areaportal ist außerdem ein Entity und zählt bei der Edict-Grenze mit.
Warum verschwindet der Raum hinter einer Tür oder einem Fenster?
Dann ist ein Portal geschlossen, obwohl du hindurchsehen kannst. Typische Ursachen sind ein Portal mit „Initial State“ auf „Closed“, das weder eine Tür noch ein Input je öffnet, eine verknüpfte Tür mit Glaseinsatz oder ein func_areaportalwindow mit zu kurzer „Fade End Distance“.