An areaportal is a brush entity,
func_areaportal, that can be used to 'seal' separate visleaves and control visibility. Areaportals are like doorways that can only be fully open or closed. When an areaportal is closed, it blocks the visibility of the geometry and other objects in the area behind it. When it is open, the geometry is visible again. Areaportals can be dynamically opened and closed while the engine is running. They are typically set to open and close from sets of
trigger_multiple brushes using the entity I/O system or attached to door entities (
prop_door_rotatings, etc.), synchronized to open and close with the door.
- 1 Properties of areaportals
- 2 Basic areaportal construction
- 3 Performance value of open areaportals
- 4 Sealing areas / areaportal leaks
- 5 Areaportals merging
- 6 Relationship to occluders
- 7 Window areaportals
- 8 Performance cost and overuse
- 9 Areaportals and water
- 10 Multiplayer games and areaportals
- 11 See also
Properties of areaportals
A standard areaportal:
- is tied to the
- must be constructed of only one brush. Areaportal entities with more than one brush will generate an error when compiled by vbsp.
- must use the
tools\toolsareaportalmaterial applied to all faces of the areaportal brush.
- cannot contain displacements and will generate an vbsp error if they do.
- must be used to seal the all areas they connect to, to avoid leaks.
- are volumes, not single surfaces. Although areaportals can be any size, usually they are constructed of thin brushes that are the size of the areas (doorways) that they connect.
- generate a new visleaf the size of the areaportal volume.
- can be set to open or close based on entity logic, or by attaching them to a door entity.
Basic areaportal construction
- Create the areaportal volume with a single brush solid, completely sealing the space between the two areas that you wish to control.
- If the areaportal is connecting two areas like a doorway, make the areaportal brush the size of the opening, and the thickness the same as the walls it is connecting. If the areas are open areas, such as an outdoor section, the thickness can be of any size (grid sizes of 8, 16, 32, etc. are typical).
- Apply the
tools\toolsareaportalmaterial to all faces of the brush.
- Tie the brush to a func_areaportal entity.
- Set the Initial State keyvalue 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. When the door is closed the Initial State of the areaportal should be Closed too, and vice versa.
Performance value of open areaportals
Open areaportals (whether they're always open, or triggered to open) have a behavior of culling geometry that is visible through the areaportal. Similar to looking through an open window of a house, only the visleaves that are directly visible through the areaportal will be rendered by the engine. In this way, the geometry in the next area is roughly 'culled' to the size of the window, decreasing the amount of geometry rendered, and increasing performance. On top of this, model (prop) geometry is not rendered at all unless part of the model is directly visible through the view frustum (or visible angle) of the areaportal. This makes open areaportals very useful to control visibility of model geometry.
Due to these performance benefits, areaportals are often used in an always-open state. An always-open areaportal is created by setting the "Initial State" keyvalue on the
func_areaportal entity to "Open". Always-open areaportals are used at the openings to other areas containing large amounts of visleaves and geometry. For example, simply placing an always-open areaportal at the end of the hallway that opens into a wider expanse can produce a substantial performance gain. While the player is inside, looking out of the doorway, only the geometry that is in the each leaf directly visible through the doorway will be drawn. A special type of areaportal entity,
func_areaportalwindow, is also used in some of these cases. The
func_areaportalwindow entity is a type of areaportal that can be open or closed based on a distance from the player instead of simply being triggered to open or close like standard
Sealing areas / areaportal leaks
It is vital that any areas that a areaportal is supposed to seal off doesn't leak into each other. Just as with regular leaks, an area of the map is only considered sealed from another if it is completely surrounded by world (non-entity) brushes (with the exception of areaportal brushes), without gaps. If there are multiple ways that areas connect, each must be filled with an areaportal.
It may help to imagine a fish tank filled with water with several holes in its sides. An areaportal must fill each of those holes, or the area will leak, generating a leak error by vbsp. Areaportals must be used to seal every entrance to the area. Detail brushes or displacements cannot 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
For optimization reasons, areaportals that share the same plane (are aligned) are automatically merged by the engine. If this behavior is unwanted, simply ensure the areaportal brushes are not along the same plane. This is usually as simple as shrinking or moving one of the areaportals slightly in the editor so they are no longer aligned. Even grid one unit is sufficient to avoid an automatic merge.
r_DrawPortals 1console command.
Relationship to occluders
Areaportals are similar to occluders in that they help control visibilty. The main differences between them are:
- Occluders only hide model (prop) geometry that is behind them. Areaportals hide all types of objects.
- Areaportals must fully seal areas (allow no leaks), while occluders can be free-standing inside areas.
- Occluders are more expensive per object than open areaportals.
- Occluders have controls for the size of objects they will hide, based upon screen area.
Areaportals 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.
One common use for
func_areaportal_window entities are for buildings in outdoor areas. They can be used to hide the contents of buildings until players are at close distances without the visual 'pop' of an standard areaportal being opened.
Performance cost and overuse
Although areaportals can give substantial performance benefits when used correctly, care must be taken with not to place too many areaportals where many of them would all be visible simultaneously. There is processing cost for each areaportal. If multiple portals are open and visible in the current view, and the portals are not culling (hiding) enough geometry, it's certainly possible that the overhead required to process the areaportals will be more costly to performance than if the portals were not there at all. Watch out for the 'worst case scenario' in these situations.
Useful console variables
You can debug and test portals in-game, using some portal-specific console variables:
- r_DrawPortals 0/1
- Outlines any portal border surface (between two areas) in green when set to "1". 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 visibility on the other side is clipped to.
- mat_wireframe 0/1/2/3
- Draws geometry in wireframe mode, making it easy to see the effects of areaportals in the level. When debugging areaportals, you should typically use mat_wireframe set to "1" or "2", as the "3" setting can hide geometry that is actually rendering.
- r_portalscloseall 0/1
- Setting this to "1" forces all areaportals 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/1
- Setting this to "1" forces all areaportals open (so that they cannot be closed).
BindToggleconsole command to allow a single key to be used to toggle a console variable.
Areaportals and water
One other tricky aspect of using areaportals 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 areaportal above the water surface, and another areaportal below it - so that they both meet at the water plane.
Multiplayer games and areaportals
Areaportals are very useful in multiplayer games. Their creation is identical to those in single-player games, but their function and usage is slightly different. With multiple players in a game server, there is less control of when an areaportal is going to be open, and level performance needs to be optimized for worst case scenarios (i.e. when all visible portals are open). Because of this, in most cases, 'always open' areaportals are placed most often, followed by areaportals linked to doors, and then areaportals controlled by triggers. In worst case scenarios, well-crafted 'always open' areaportals will increase performance more than portals that are designed to be triggered.