- 1 Overview
- 2 Open portals
- 3 Creating an area portal
- 4 Sealing an area / Portal leaks
- 5 Compiling Portals
- 6 Portal specific console variables
- 7 Window portals
- 8 Performance cost and overuse
- 9 Area portals and water
- 10 Portals in multiplayer games
- 11 Further reading
- 12 Example maps
Area portals are used for in-game control of the visibility of world geometry from one area to another. (To do: Is it called "areaportals" instead? The Hammer error logs just talks about portals. I'll call them "area portals" for now.) They are similar to Occluders (which instead blocks models).
A portal has two states: Open or closed. While in its open state, the portal allows visibility of world brushes between its bordering areas. When the portal is closed, it blocks this visibility instead. (The result is black and opaque.) You can think of it like an invisible door, which still blocks visibility.
Area portals are typically linked to doors, matching their open/closed state, making the engine ignore drawing the world geometry behind a door while it is closed (despite the door not being able to block visibility on its own). They may also be triggered to open or close through the I/O system (like for example trigger_multiples).
For an easy-to-understand tutorial on area portals, see the area portal tutorial.
Additionally, open area portals will also limit the amount of geometry rendered to the geometry that is directly visible through it, increasing performance.
Because of this behavior, always-open area portals are sometimes used at the doorways to large outdoor areas. Simply placing an always-open area portal at the end of the hallway that opens into a wide expanse, can produce a substantial performance gain. While the player is inside, looking out of the doorway, only the geometry that is in the leaves directly visible through the doorway will be drawn.
Creating an area portal
- Create the portal volume with a brush solid, completely sealing the gate between the areas that you wish to control. (To do: Can it be of any shape, or does it have to be block-shaped (cube-shaped)? Does the engine handle block shapes better?)
- Make it just as thick as its door (or frame, in case there is no door). (Area volumes are designed to be very thin. One of its two main surfaces sets the border between the areas, while the opposite surface blocks the visibility between them. There also seems to be no way to specify exactly which of these two surfaces that will be used for which purpose. The compiler decides this, probably according to the leaf compile order. This order can be hard to keep track of, so to be on the safe side, and considering that both surfaces cut visleaves, a portal should stretch between two acceptable border positions, usually with the same thickness as its door or frame.)
- Texture all the faces of the brush with the
- Tie the brush to a func_areaportal entity.
- Make sure that the Initial State keyvalue is correctly set (so that it doesn't end up blocking visibility when it shouldn't). If you wish to link it to a named door, set the Initial State of the portal to the same initial state as the door, and put the name of the door in the Name of Linked Door keyvalue of the portal.
Sealing an area / Portal leaks
It is vital that the areas that a portal is supposed to seal off doesn't leak into eachother. Just as with regular leaks, an area of the map is only considered sealed from another if it is completely surrounded by world brushes (with the exception of area portal brushes), without gaps. Detail brushes or displacement brushes can not seal an area. If the compiler can still find a way between the two main surfaces of any one portal, it will report a portal leak.
When they compile correctly, the BSP program will report the following:
However, if a leak occurs, vbsp will instead report the following:
Brush <brush number>: areaportal brush doesn't touch two areas done
These error messages are not as easy to spot as normal leak error messages, but when it comes to locating the leak in the map, the BSP program will generate a pointfile to help you, just as for regular geometry leaks.
Glview will display area portals as gray obstructions.
Portal specific console variables
You can debug and test portals in-game, using a couple of portal specific console variables:
"Disable area to area connection testing." Probably something to do with area portals. (To do: Please find out what it does.) Seems to fix the stuttering bug if activated! (I'm thinking that the opening of area portals in mid-game is the actual cause of the infamous HL2 stutter, and setting this to 1 will instead load all areas at once. (To do: Again, please verify this.))
No idea what this does, but it has got "areaportals" in it. According to r_areaportal.cpp, line 468 it has been commented out due to occationally huge performance hits.
- r_ClipAreaPortals 1
- This is the default setting.
- r_ClipAreaPortals 2
- Line 500: "Just leave the area clipping how it was (for debugging)."
- r_DrawPortals 0
- This setting is default. Portals are not drawn.
- r_DrawPortals 1
- Outlines any portal border surface (between two areas) in green. (Sometimes more than one portal is condensed into one.) If the portal belonging to it is open, a second green box is also drawn, showing what the geometry on the other side is clipped to.
- r_portalscloseall 0
- This setting is default. Portals are displayed according to their state.
- r_portalscloseall 1
- Forces all portals closed (so that they cannot be opened). Overrides
r_portalsopenall 1. (Try this if portals don't seem to be doing anything. It can tell you whether the problem is just that the portals aren't closing properly.)
- r_portalsopenall 0
- This setting is default. Portals are displayed according to their state.
- r_portalsopenall 1
- Forces all portals open (so that they cannot be closed).
- r_PortalTestEnts 0
- Entities inside visible leaves are drawn, even these entities are not visible themselves.
- r_PortalTestEnts 1
- This setting is default. Clip entities against portal frustrums. (Don't draw entities that aren't directly visible through the portal.)
No idea what this does, but it is mentioned in r_areaportal.cpp, line 293.
- r_snapportal 1
- Sets up some kind of drawing of a box with the origin at the player origin. (It seems impossible to get rid of without restarting the game.)
- r_snapportal 2
- Sets up a different kind of drawing.
Area portals can be used for windows too, with the use of the func_areaportalwindow entity. This type of portal instead controls the transparency of a window depending on how close the player is to it, effectively shutting out any scenery beyond it if the player isn't interested in it.
Performance cost and overuse
While area portals are designed to save resources (by hiding unnecessary geometry) giving substantial performance benefits when used correctly, each area portal require some run-time calculations whenever open and visible in the current view. This presents somewhat of a tradeoff between the benefit and the cost of the portal, as too many open area portals simultaneously visible in the current view, while not hiding enough geometry, could even cost more performance than they save.
Area portals and water
One other tricky aspect of using area portals is that they are not allowed to cross water boundaries, like the water surface. To accomplish this, you will need to divide the portal into two - one portal above the water surface, and another portal below it - so that they both meet at the water plane.
Portals in multiplayer games
Area portals are overall somewhat less useful in multiplayer (and especially deathmatch) games than in singleplayer. The multiple player presence will not only prevent portals from closing as often (to free resources) but players in both of its areas renders even renders them unable to hide non-visible geometry, making them completely useless, and only costing resources instead of saving them. Only seal off rarely frequented areas of such a map, possibly with doors that automatically close.
Unfortunately, there is no SDK sample map for Area Portals.