Visportals: Difference between revisions
Springheel (talk | contribs) |
Update troubleshooting section with minor formatting and mention DR's ability to load the pointfile without renaming. |
||
(71 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
''written by Fidcal'' | ''written by Fidcal. Visportals, Func_statics and Worldspawn Brushes added by Sotha.'' | ||
== Video Introduction to Visportals == | |||
[https://youtu.be/RmKjmt7IJr8 Video Introduction to Visportals.] | |||
== What are visportals? == | == What are visportals? == | ||
Visportals are a very important part of mapping. They are a kind of brush that helps separate your map into individual areas, which is important for both rendering and sound propagation. | Visportals are a very important part of mapping. They are a kind of brush that helps separate your map into individual areas (called visleafs), which is important for both rendering and sound propagation. | ||
Without visportals, the Doom engine would render the entire map even if the player can only see one small area. This would reduce performance and slow the game down. | Without visportals, the Doom engine would render the entire map even if the player can only see one small area. This would reduce performance and slow the game down. | ||
Line 8: | Line 12: | ||
Visportals are also very important for sound propagation. Without them, sounds can travel through brushwork and reach areas of the map that they shouldn't (see ''Sound Propagation'' at the bottom of the page). | Visportals are also very important for sound propagation. Without them, sounds can travel through brushwork and reach areas of the map that they shouldn't (see ''Sound Propagation'' at the bottom of the page). | ||
Visportals determine how far the engine should render from the player's position. When a visportal is in the player's view, the engine tests to see if there is a second visportal viewable from the position of the first. If yes then it tests to see if a third one can be seen from the second one. If the third is not viewable from the first then the engine won't waste time rendering the map beyond it. If it is, then the engine tests for a fourth one and so on. So for example, with a long corridor with lots of 90 degree turns in it and visportals at every bend then the engine will only render the section you are in plus the next section | |||
Visportals determine how far the engine should render from the player's position. When a visportal is in the player's view, the engine tests to see if there is a second visportal viewable from the position of the first. If yes then it tests to see if a third one can be seen from the second one. If the third is not viewable from the first then the engine won't waste time rendering the map beyond it. If it is, then the engine tests for a fourth one and so on. So for example, with a long corridor with lots of 90 degree turns in it and visportals at every bend then the engine will only render the section you are in plus any parts of the next section you can see. But as you get near to it and can see further down it to the next bend's visportal then it will render the next one too. | |||
Anything in the visleaf that the player is currently in is rendered (if it is your field of view) regardless of whether it is behind worldspawn. But things in an adjacent visleaf will not be rendered if they are behind worldspawn. The engine still has to calculate what the player can see and what he can't, and this still uses resources, but far less than if it were in the same visleaf as the player. Any visleaf that is behind a closed portal is automatically beyond what the player can see, to the engine can skip testing it completely. This is why closed visportals are so valuable for performance. | |||
''[stgatilov --- on a minor note, the engine still has to check for shadows coming out from closed visleafs; so even a closed visleaf needs some processing]'' | |||
The console command '''r_showPortals 1''' shows processed visportals as wireframe in-game for testing - even right through walls they are visible. A green wireframe is an 'open' visportal and renders everything beyond it up to the next visportal. A red wireframe is a 'closed' visportal with nothing rendered beyond it and no further visportals beyond that are even processed so are not visible at all. If a visportal does not show then it is either beyond range of processing or it is not working so check it is set up correctly. | The console command '''r_showPortals 1''' shows processed visportals as wireframe in-game for testing - even right through walls they are visible. A green wireframe is an 'open' visportal and renders everything beyond it up to the next visportal. A red wireframe is a 'closed' visportal with nothing rendered beyond it and no further visportals beyond that are even processed so are not visible at all. If a visportal does not show then it is either beyond range of processing or it is not working so check it is set up correctly. | ||
Line 22: | Line 30: | ||
You can see that for the purpose of testing performance use 2 above which shows all that would be rendered (whether visible to the player or not.) You can use 3 to see ''all'' triangles up to the next closed visportal but remember not all of it will be rendered so will not affect performance. | You can see that for the purpose of testing performance use 2 above which shows all that would be rendered (whether visible to the player or not.) You can use 3 to see ''all'' triangles up to the next closed visportal but remember not all of it will be rendered so will not affect performance. | ||
You | You ''should'' also use '''r_useScissor 0''' to show geometry outside the visportal wireframe that Doom still sends to the video card. | ||
<br>Scissors happen on the GL driver side after geometry has already been uploaded. | |||
<br> They help with performance but the best performance happens when you prevent the geometry from being uploaded to your GPU in the first place. | |||
'''Remember''' to return to '''r_useScissor 1''' when you are done with "visportal testing" so that scissors can still | |||
<br>optimize away geometry that you were unable to optimize away with visportals. | |||
Here is a short video with a decent visual breakdown: | |||
[http://www.gdcvault.com/play/1014234/Excerpt-Quake-Postmortem-Optimizing-Level Video] | |||
Another video: | |||
[http://youtu.be/cy4FIE7BhCQ http://img.youtube.com/vi/cy4FIE7BhCQ/1.jpg] | |||
== How and where to create visportals == | == How and where to create visportals == | ||
Line 39: | Line 60: | ||
=== Where to place your Visportal === | === Where to place your Visportal === | ||
It will eventually be wedged tight like a plug into gaps, doorways, etc. between areas. The edges of the visportal-textured face of visportals should be completely sealed by or in solid ''worldspawn'' brush that has no gaps. The brush '''must''' be a child of worldspawn and '''not''' an entity. This is true even if the visportal is within a door (see next section.) For the visportal to be effective it does not matter if the rest of the visportal brush sticks out into space so long as the edges of the visportal-textured face are surrounded by worldspawn brush and/or another visportal brush (see later) In practice you will probably put most fully within a corridor or doorway, a city street (yes, the sky above is solid worldspawn brush), etc. Irregular shaped gaps must still be plugged with a rectangular visportal which should then overlap into the solid worldspawn and leave no gaps. This will also make sound propagation work correctly (see ''Sound Propagation'' later.) | It will eventually be wedged tight like a plug into gaps, doorways, etc. between areas. The edges of the visportal-textured face of visportals should be completely sealed by or in opaque (i.e. solid) ''worldspawn'' brush that has no gaps. The brush '''must''' be a child of worldspawn and '''not''' an entity. This is true even if the visportal is within a door (see next section.) For the visportal to be effective it does not matter if the rest of the visportal brush sticks out into space so long as the edges of the visportal-textured face are surrounded by worldspawn brush and/or another visportal brush (see later) In practice you will probably put most fully within a corridor or doorway, a city street (yes, the sky above is solid worldspawn brush), etc. Irregular shaped gaps must still be plugged with a rectangular visportal which should then overlap into the solid worldspawn and leave no gaps. This will also make sound propagation work correctly (see ''Sound Propagation'' later.) | ||
Each area you thus created must be totally enclosed with worldspawn brushes with no gaps of either space else an entity. So a closed building with visportals at the doors but a tiny gap under the eaves of the roof won't work! Also avoid only blocking gaps with entities whether brushes or models. For example, a two-sided window entity that completely fills the opening will not seal the area for portalling purposes. Do not put in a visportal unless the window is either transparent or can be opened (like a door.) Instead put in a worldspawn brush with nodraw texture on it so it will not be visible or collidable just in front of the window. Or if you are using two windows back to back (say a lit one outside and an unlit one inside then a thin caulk brush between them. | Each area you thus created must be totally enclosed with worldspawn brushes with no gaps of either space else an entity. So a closed building with visportals at the doors but a tiny gap under the eaves of the roof won't work! Also avoid only blocking gaps with entities whether brushes or models. For example, a two-sided window entity that completely fills the opening will not seal the area for portalling purposes. Do not put in a visportal unless the window is either transparent or can be opened (like a door.) Instead put in a worldspawn brush with nodraw texture on it so it will not be visible or collidable just in front of the window. ''[not sure what this means, but note that nodraw textures DO NOT seal visleafs. As far as visportals are concerned, they don't exist]'' Or if you are using two windows back to back (say a lit one outside and an unlit one inside then a thin caulk brush between them. | ||
Generally you will place visportals on bends in the terrain around which the player cannot see from the current viewpoint. Avoid placing visportals in a line along a corridor or street for example. Since the player can see straight down through them all then they serve no purpose as they will all be open and visportals themselves create extra triangles and complexity (see downside section below.) | Generally you will place visportals on bends in the terrain around which the player cannot see from the current viewpoint. Avoid placing visportals in a line along a corridor or street for example. Since the player can see straight down through them all then they serve no purpose as they will all be open and visportals themselves create extra triangles and complexity (see downside section below.) | ||
Line 51: | Line 72: | ||
Don't get too hung up on perfect placement of every last visportal. Generally if you follow this guide and use your judgement you achieve a satisfactory game performance. Examine some large maps that you know work well to get some ideas where visportals are placed using the '''r_showPortals 1''' command. | Don't get too hung up on perfect placement of every last visportal. Generally if you follow this guide and use your judgement you achieve a satisfactory game performance. Examine some large maps that you know work well to get some ideas where visportals are placed using the '''r_showPortals 1''' command. | ||
What if you put visportal texture on | What if you put visportal texture on many faces of the visportal brush? Only one arbitrarily chosen face will be effective, and dmap will produce console warning about this situation. Basically, the engine does not support such brushes, so better use nodraw on all surfaces except the one face with visportal texture. | ||
===Multiple Joined Visportals=== | ===Multiple Joined Visportals=== | ||
Line 61: | Line 78: | ||
== Visportals and doors == | == Visportals and doors == | ||
A visportal in contact with a door that has an openable property | A visportal in contact with a door that has an openable property automatically becomes "blocking" when the door is closed. Blocking visportals are always considered closed. In fact, they provide additional performance benefit over ordinary (i.e. nonblocking) closed visportals. For instance, objects behind ordinary closed visportals can still throw shadows which are visible to the player, so the engine has to process them. But blocking visportals block everything including light and shadows, so the renderer skips all visleafs behind them even when looking for shadow casters. | ||
Of course, when you open a closed door, its visportal becomes nonblocking/ordinary again, and switches between open and closed state as usual. So when you first go through a door and leave it open then its visportal will be open as you look immediately back at it. But as you then proceed further through other visportals, the door visportal will eventually close (prevent rendering through it) even if the door itself is left open. | |||
Line 68: | Line 86: | ||
Note that the visportal only needs to be in contact with the door to be affected by it. Normally you would place the visportal within the door but it actually only needs its visportal-textured surface to touch it. This means that if you have a door that is stood in front of an opening in a wall then you cannot put the visportal inside the door because it will not be surrounded by solid brush. But you can put a visportal just inside the opening and flush with the mouth of the opening and the door immediately in front of that and in contact with the visportal. You can test this by placing the door offset well to one side but part of it still in contact with the visportal. In game you can see the opening as the door is only partially covering it. When the door is closed the visportal closes and stops rendering through the doorway. You will see this as a black panel in the doorway. As the door opens the black panel disappears and you can see through the doorway again. You might think that from the other side the black panel would obscure the door when closed but it doesn't. With the door centred in its normal position, typically you might have an entity frame around the door. If you had a solid brush frame without gaps then the visportal could be inside the door if you wanted as it would then have solid all round its edges. In many cases of course, the door frame, whether entity or brush, would be within the solid brush doorway anyway. | Note that the visportal only needs to be in contact with the door to be affected by it. Normally you would place the visportal within the door but it actually only needs its visportal-textured surface to touch it. This means that if you have a door that is stood in front of an opening in a wall then you cannot put the visportal inside the door because it will not be surrounded by solid brush. But you can put a visportal just inside the opening and flush with the mouth of the opening and the door immediately in front of that and in contact with the visportal. You can test this by placing the door offset well to one side but part of it still in contact with the visportal. In game you can see the opening as the door is only partially covering it. When the door is closed the visportal closes and stops rendering through the doorway. You will see this as a black panel in the doorway. As the door opens the black panel disappears and you can see through the doorway again. You might think that from the other side the black panel would obscure the door when closed but it doesn't. With the door centred in its normal position, typically you might have an entity frame around the door. If you had a solid brush frame without gaps then the visportal could be inside the door if you wanted as it would then have solid all round its edges. In many cases of course, the door frame, whether entity or brush, would be within the solid brush doorway anyway. | ||
''Geep comments: This is pertinent for surface-mounted sliding doors. Unless they include transparency, such as ductwork grill doors (whether sliding or rotating), in which case the next section rules.'' | |||
=== Windows, Doors with windows, bars, etc. === | === Windows, Doors with windows, bars, etc. === | ||
Openable doors that let you see through them such as windows, doors with windows, barred gates, etc. should not be in contact with a visportal. When the door is closed it will automatically close any visportal whose effective surface is in touch with it. The visportal will not then permit any rendering through it and will show as a black panel in the window or between the bars of a gate. Instead, move the visportal | Openable doors that let you see through them such as windows, doors with windows, barred gates, etc. should not be in contact with a visportal. When the door is closed it will automatically close any visportal whose effective surface is in touch with it. The visportal will not then permit any rendering through it and will show as a black panel in the window or between the bars of a gate. Instead, move the visportal away from the door. It will still function effectively as a normal visportal just as if the door were not there. This does not of course apply to simulated windows such as a glazed textured panel on a door texture where you cannot actually see through. | ||
All doors and windows that do not have an openable property can have a visportal in touch with them as it will not be affected by them and it will just function as a normal visportal. | All doors and windows that do not have an openable property can have a visportal in touch with them as it will not be affected by them and it will just function as a normal visportal. | ||
{{red|Rev. 2.00:}} | |||
Starting with Rev. 2.00, you can touch a see-through door or window with a visportal, and the portal will not close when the door/window is closed, as long as you use the following spawnarg '''on the door/window''' (not the info_portalsettings entity): | |||
* '''transparent''' "If set to 1 (0 by default), a see-through door can touch a visportal and the visportal won't close when the door is closed." | |||
This is useful when you want the opening or closing of the door to affect the sound loss across the portal, but not affect visibility through the door/window. Imagine a closed window that muffles a sound beyond it, and as the window opens, the sound gets louder. | |||
==Visportal switches: func_portals== | ==Visportal switches: func_portals== | ||
The preceding section ''Visportals and doors'' makes clear that doors can function like switches to enable and close visportals in contact with them. ''func_portals'' can be used to enact further control over portals. You can place a ''func_portal'' entity so that it intersects with a visportal, and then trigger the func_portal to close or open the visportal. A second control method is had by using the ''portal_dist'' and ''distcheck_period'' properties on the ''func_portal''. They control the distance to the player and how frequently (in seconds) this distance should be checked, respectively, and make explicit triggering of the ''func_portal'' unnecessary. As with doors, even if enabled the visportal will not be open even if it is in the player's view. | The preceding section ''Visportals and doors'' makes clear that doors can function like switches to enable and close visportals in contact with them. ''func_portals'' can be used to enact further control over portals. You can place a ''func_portal'' entity so that it intersects with a visportal, and then trigger the func_portal to close or open the visportal. A second control method is had by using the ''portal_dist'' and ''distcheck_period'' properties on the ''func_portal''. They control the distance to the player and how frequently (in seconds) this distance should be checked, respectively, and make explicit triggering of the ''func_portal'' unnecessary. As with doors, even if enabled, the visportal will not be open even if it is in the player's view. Note, if you have a mover (door/window) in contact with the visportal, it will affect it as well, so typically a visportal controlled by func_portal is placed away from the mover, or use spawnarg "transparent" set to 1. | ||
Another clever trick exists with regard to ''func_portal''s: you can also build a func_static over the visportal, and target it with the ''func_portal'' as normal. Now, in addition to opening and closing the portal, this will also toggle the drawing of the ''func_static''. This means you could place an appropriate texture (perhaps a low resolution image of a room's interior, drawn over a window) and have it turn on or off based on the player's distance away. From a distance, the player wouldn't be able to tell that the the entire room wasn't being rendered. This can be an effective way to create the illusion of long view distances. | |||
Note that the func_static must touch the visportal in order to work. | |||
''One way to make this work is to create a patch, make it a func_static. Texture the patch, and then target the func_portal at that func_static. You must then add "hide" "1" to the func_static patch. There may be other ways to make this work, but I had a lot of trouble until I took these steps. -- Springheel'' | |||
An interesting, recent discovery that needs some testing is that apparently: you can take one visportal and cut it in half, and then put different func_portals on each half in order to close them at different ranges. That has interesting implications for wide city streets. They require big visportals, but if you can split them up and independently control each part, there may be some benefits there. http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/?p=370473 | |||
== Need I design, even compromise my map to make best use of visportals? == | == Need I design, even compromise my map to make best use of visportals? == | ||
You need to design your map from the start as a series of connected boxes (brushes) with the player's view and visportals in mind. And yes, sometimes you might need to add a bend you don't want or obstruct a view in some way so you can put in another visportal if you are having or expecting slow down in a large and/or complex area. This is a matter of experience. If you have large complex areas and are experiencing frame lag but can see no obvious place to put a visportal then you might need to compromise your terrain and add some solid brush barriers to block certain views with visportals in the access round or through them. | You need to design your map from the start as a series of connected boxes (brushes) with the player's view, sound propogation, and visportals in mind. And yes, sometimes you might need to add a bend you don't want or obstruct a view in some way so you can put in another visportal if you are having or expecting slow down in a large and/or complex area. This is a matter of experience. If you have large complex areas and are experiencing frame lag but can see no obvious place to put a visportal then you might need to compromise your terrain and add some solid brush barriers to block certain views with visportals in the access round or through them. | ||
Note that it is not essential that visportals be only at the actual joins between brushes; they still work even if they are half way down a corridor so long as they are wedged in tight without gaps. But you will mostly place them at joins. | Note that it is not essential that visportals be only at the actual joins between brushes; they still work even if they are half way down a corridor so long as they are wedged in tight without gaps. But you will mostly place them at joins. | ||
Line 92: | Line 123: | ||
It is not necessary to put visportals at every tiny bend in the map; in fact that should be avoided in smaller areas because visportals themselves create extra triangles and complexity (see downside section below.) Try to keep in mind what will be rendered through the visportals and judge what would ''not'' cause frame lag slowdown if the player could actually see that view. Three or four bends without visportals in a restricted air duct is not going to cause any problem if the duct is correctly visportalled at the ends for example. | It is not necessary to put visportals at every tiny bend in the map; in fact that should be avoided in smaller areas because visportals themselves create extra triangles and complexity (see downside section below.) Try to keep in mind what will be rendered through the visportals and judge what would ''not'' cause frame lag slowdown if the player could actually see that view. Three or four bends without visportals in a restricted air duct is not going to cause any problem if the duct is correctly visportalled at the ends for example. | ||
== Is there a downside? == | == Is there a downside? == | ||
Line 119: | Line 148: | ||
Sound travels | Sound ''going to the AI'' travels the shortest distance through a visportal, passing at any point on the visportal surface. Mappers should always use rectangular visportals unless you have no choice with an awkwardly shaped gap or if the gap is out of range of AI, for example along a sloping roof where AI never go. '''It also still assumes that when you do have four sides, they are perpendicular.''' If you have some non-90 degree angles between the sides, some wierdness may ensue. For example, an AI that is alerted in the dark (or facing away) by hearing a sound from the player that passes through an irregular visportal might run to the center of the visportal rather than directly to where the player made the noise. Irregular visportals large enough to make this effect noticeable are likely to be uncommon. | ||
This will be okay for smaller visportals, but the error (path difference from the minimal path) will get more noticeable the larger the visportal. | This will be okay for smaller irregular visportals, but the error (path difference from the minimal path) will get more noticeable the larger the visportal. | ||
Visportals function individually even if joined together into complex shapes. So a rectangle at ground level topped by an angled visportal above it tilting out over a roof will be treated separately not as one aperture. | Visportals function individually even if joined together into complex shapes. So a rectangle at ground level topped by an angled visportal above it tilting out over a roof will be treated separately, not as one aperture. | ||
The bottom line is, with any non-rectangular visportals keep the above in mind and if in doubt then consider early testing of AI's alert to player sound. | The bottom line is, with any non-rectangular visportals keep the above in mind and if in doubt then consider early testing of AI's alert to player sound. | ||
Visportals do NOT need to be closed to correctly channel sound to the player. Sometimes it is worth adding visportals even if they will not help with rendering (because they will always be open) in order to make sound travel the way it should. | Visportals do NOT need to be closed to correctly channel sound to the player. Sometimes it is worth adding visportals even if they will not help with rendering (because they will always be open) in order to make sound travel the way it should. | ||
To make less sound go through a visportal (through a small hole, for example): | |||
Soundprop can use info_locationSeparator or info_portalSettings to make sound incur a certain loss when going through the portal it's touching. The key/value pair is the following: | |||
sound_loss "Soundprop: Loss in dB incurred when a sound travels through this portal. Cumulative with door loss if a door is present." | |||
The loss must be a positive number, and negative numbers will automatically be converted to positive. | |||
{{red|Rev 2.00:}} | |||
Prior to Rev 2.00, '''sound_loss''' affected the sound propagation to AI '''only'''. Sound propagation to the player was not affected. | |||
Starting with Rev 2.00, '''sound_loss''' is also used in determining sound volume to the player. This aligns what AI hear with what the player hears. It also allows sound coming through the door to increase as the door opens, or decrease as the door closes, making for a more realistic experience. | |||
For details study: | For details study: | ||
Line 133: | Line 175: | ||
[[Sound Propagation: Part 2]] | [[Sound Propagation: Part 2]] | ||
== | |||
== Engine changes == | |||
Several bugs in dmap related to visportals were fixed in TDM 2.08. The technical description is provided [https://bugs.thedarkmod.com/view.php?id=5129#c12147 in issue #5129]. Here is the rough summary: | |||
# Normally, leaky visportals should be dropped by dmap, but a lot of them actually made it into the final maps. As a rule of thumb, a few dozens of functioning visportals in every FM released so far are leaky. Most of them cause no serious issues, although some of them cause thin black stripes where they leak. The new dmap drops all leaky visportals without exceptions. It means that if you compile an old FM with the new dmap, a lot of visportals will be lost. | |||
# A visportal had some weird effects outside of its bounds on its plane. This caused terrible trouble when several visportals lied on the same plane. Aside from that, it could produce ugly black panels on places without any visportals. All of this is now fixed, but there is a chance that some existing map somehow relied on the old erratic behavior. | |||
# Normally, if a brush has at least one non-opaque side (i.e. non-solid face), then it is considered non-opaque and does not seal visportals and areas. A bug caused some brushes with exactly one non-opaque side to be considered opaque. It is now fixed, but as the result some rare brushes on existing maps no longer seal areas if you dmap them with recent engine. This can lead to global leaks and dropped visportals. | |||
The changes seriously affect how visportalling works on existing maps. If you need to dmap an FM which was released before 2.08, then you have a choice: | |||
* Fix all the visportal warnings which dmap spits to console (see the next section). This will take some time and effort, and will probably need additional beta testing after that. | |||
* Enable old and buggy behavior of visportals, so that dmap works exactly as it did when FM was released. To achieve this, you have to set the following cvars (note that they do '''not''' persist between sessions): | |||
*# dmap_bspAllSidesOfVisportal 0 | |||
*# dmap_fixVisportalOutOfBoundaryEffects 0 | |||
*# dmap_fixBrushOpacityFirstSide 0 | |||
== Troubleshooting == | |||
Starting from TDM 2.08, dmap provides several useful diagnostics for visportalling problems. Every visportal with a problem is reported to the game console as a warning. You might want to [[Reporting Problem#condump|enable logFile]] to make it easier to read the whole dmap output. Aside from that, most warnings are accompanied by .lin files (generated near your .map), which can be viewed in DR. | |||
Below you can see the different types of warnings produced by dmap. | |||
;<tt>Portal %d at (%s) dropped</tt> | |||
: The mentioned visportal does not separate the space into two isolated areas. This is usually called "internal leak". Such visportal is dropped because it appears to be fully contained in one visleaf, while every visportal must separate two different visleafs from each other. | |||
:Remember, the visportal face must be surrounded by opaque worldspawn brushes. Entities have no effect on visportals and visleafs, and brushes with any nodraw material are also ignored. If brief inspection does not help, load the .lin file in DR: it shows a closed path passing through the visportal which is not blocked by anything. In order to make visportal functional, you must block this path at least somewhere: the exact understanding of what went wrong and how to fix it is up to you. | |||
;<tt>Portal %d at (%s) dropped as leaky</tt> | |||
:This is popular subcase of "dropped" warning, implemented in TDM 2.10. | |||
:A proper visportal must have all of its boundary edges fully in contact with opaque geometry or other visportals. You should see "as leaky" clarification when this rule is broken. | |||
:To fix the visportal, inspect its boundary, i.e. where it touches solid geometry. | |||
: '''TIPS:''' If you have any portals "dropped as leaky", save yourself some time by correcting them first. This will often stop other (good) visportals from being dropped. The .lin file discussed below will often show you exactly where the boundary problem is. Be aware that occasionally you may find a "dropped" portal that should have been tagged "dropped as leaky"; the detection algorithm is approximate. | |||
;<tt>Portals [%s] at (%s) overlap</tt> | |||
:Two or more visportals geometrically overlap, which is going to be confuse the engine. In most cases the offending visportals are exactly equal, which is why it is very hard to notice without warning. Note that it is OK for visportals to touch each other. | |||
:In order to fix the problem, find both visportals in DR, and probably just delete one of them. | |||
;<tt>Portal %d at (%s) is useless</tt> | |||
:No part of this visportal is within the playable space. Sometimes such visportal is fully inside opaque brushes or lie on the boundary of opaque brush. Sometimes the whole visportal hangs somewhere in outer space, outside of any playable locations. | |||
: Find this visportal in DR, verify that it is not necessary, and delete it. | |||
;<tt>brush %d has multiple area portal sides at %s</tt> | |||
:More than one side/face of this brush is marked with visportal texture, which is not supported by engine. Remember that visportal brush must have exactly one face with visportal texture and all the other faces with nodraw texture. | |||
:First, find the brush. If any face has visportal material by mistake, change it to nodraw material. If both sides should work as visportals, then split the brush into two, each with one visportalled face. | |||
When investigating a particular warning, there are several ways to find and debug the visportal. | |||
# The brush number of the problematic portal is reported in the warning itself (like: <tt>Portal 5237</tt>). You can quickly find the brush in DR by using "Map -> Find Brush" feature, setting "Entity Number" to 0. Beware that brush numbering changes when you modify the map. If the numbers lead you to non-visportal brushes, then you most likely need to rerun dmap to get the new numbers. | |||
# The warning usually contains world 3D coordinates (like: <tt>at (347.25 -490 790)</tt>). These coordinates are much more stable that brush numbers and won't change between runs. You can use '''setviewpos''' in-game to teleport to specified coordinates, and hopefully DR will have such feature too in future. | |||
# For every dropped or overlapped visportal, a leakfile is dumped into a .lin file. The filename is reported right after the warning itself (like: <tt>saved mapname_portalL_coords.lin (%i points)</tt>. The capital letter after the word "portal" indicates the type of problem (e.g., with TDM 2.08, O = Overlap, L = dropped/Leaked; with TDM 2.10, O = Overlapped, D = Dropped, L = dropped as Leaky). The file is located in the same directory where .map file is located. In order to open it in DR, use the '''File → Pointfile''' menu option, which will show a dialog allowing you to choose the appropriate .lin file if there is more than one available. Use '''View → Camera → Next/Previous leak spot''' (or respectively '''Ctrl+Shift+K''' and '''Ctrl+Shift+L''') to teleport to leak location and travel along its points. Fly around: follow the path, see where it crosses something that you considered opaque while it is not. | |||
If you have fixed all warnings but some visportal doesn't work at all (i.e. does not show as either red or green while you are directly in its area and looking at it and you have '''r_showPortals''' enabled), then make sure the visportal is worldspawn, not some entity with a misapplied visportal texture. | |||
Expand the section below to read some outdated information. It is useless starting from 2.08. | |||
<div class="toccolours mw-collapsible mw-collapsed" style="width:100%; overflow:auto;> | |||
There are two possible problems I can think of: the visportal doesn't work at all or it works yet there is too much being rendered giving poor performance and frame lag. The latter problem is a matter of experience and experimentation. Often much ingenuity is needed to place visportals to reduce the size of areas being rendered at any one time. There is probably a different solution for every situation. Ultimately you might be forced to change the terrain to help visportalling. | There are two possible problems I can think of: the visportal doesn't work at all or it works yet there is too much being rendered giving poor performance and frame lag. The latter problem is a matter of experience and experimentation. Often much ingenuity is needed to place visportals to reduce the size of areas being rendered at any one time. There is probably a different solution for every situation. Ultimately you might be forced to change the terrain to help visportalling. | ||
If a visportal doesn't work at all (eg, does not show as either red or green while you are directly in its area and looking at it and you have '''r_showPortals''' enabled) then | If a visportal doesn't work at all (eg, does not show as either red or green while you are directly in its area and looking at it and you have '''r_showPortals''' enabled) then that means there is a "leak" in that ''area''. It does not necessarily mean the visportal itself is the problem. | ||
Try the following to track down the problem. | |||
'''Check the visportal itself:''' | |||
* Check which face of the visportal is facing which way. It sometimes happen one clones a visportal and rotates it the wrong way without realizing. So the wrong face is in the right place but the visportal face is not in contact with worldspawn. | * Check which face of the visportal is facing which way. It sometimes happen one clones a visportal and rotates it the wrong way without realizing. So the wrong face is in the right place but the visportal face is not in contact with worldspawn. | ||
Line 147: | Line 247: | ||
* Check all surrounding items to see if any are entities. Remember, the visportal '''face''' must only be surrounded by worldspawn brushes. It seems to be mostly OK if the visportal ''cuts through'' an entity so long as it meets worldspawn at its edges. | * Check all surrounding items to see if any are entities. Remember, the visportal '''face''' must only be surrounded by worldspawn brushes. It seems to be mostly OK if the visportal ''cuts through'' an entity so long as it meets worldspawn at its edges. | ||
'''Check the area for internal leaks:''' | |||
* Clone the visportal and drag one edge to one side, that is, reduce its size to say half. | |||
There is a way to test an individual area for leaks. It sounds more complicated than it is. | |||
1. Filter off all entities. Make sure visportals are NOT filtered. | |||
2. Select your entire visible map (which will now be only brushwork). | |||
3. Copy and paste into a new blank map. | |||
4. Put the player start into the area where you think you have an internal leak. | |||
5. Take the visportals sealing that area and texture them with a solid texture. | |||
6. Make sure there is only void around the map (if you have your entire map encased in a skybox brush, open a hole in a distant corner of the map). | |||
7. Save the map as a new filename and run dmap. If you do not get a leak, then the area with the player start is properly sealed. Move the player start to a new area and repeat as needed. | |||
8. If you do get a leak, open the pointfile in DR. Because the player entity is the only entity in the map, the red line will always start there and will show you where the gap is. | |||
9. Go back to your original map and fix the gap. Repeat as needed. | |||
'''Having visportals that line up in parallel with each other can cause problems, usually appearing as pieces of wall that appear black or show skybox. This can usually be fixed by moving a visportal slightly or turning one on a slight angle so they're no longer parallel.''' | |||
'''If all else fails, try:''' | |||
* Clone the visportal and drag one edge to one side, that is, reduce its size to say half. | |||
* Select the original and drag its opposite edge the other way so you now have two visportals pressed together and which together fill the gap. Guess which side unless you suspect one side particularly (see later.) | * Select the original and drag its opposite edge the other way so you now have two visportals pressed together and which together fill the gap. Guess which side unless you suspect one side particularly (see later.) | ||
* Change one of the visportals to any normal visible simple texture, stone, wood, whatever so that now the original gap is smaller and filled by just one smaller visportal. (with hindsight, I think this would probably work anyway and might even be better just leaving it as visportal so you can see which one works but I'll continue with what I did!) | * Change one of the visportals to any normal visible simple texture, stone, wood, whatever so that now the original gap is smaller and filled by just one smaller visportal. (with hindsight, I think this would probably work anyway and might even be better just leaving it as visportal so you can see which one works but I'll continue with what I did!) | ||
Line 158: | Line 286: | ||
* The result might make not seem to make sense but at least if you locate the error you can try things to solve the problem. I had a visportal up to the sky and on its left against the top of a triangle of bricks on which rested a roof. The visportal seemed to be perfectly surrounded by worldspawn but I reduced it slightly with just a slim temporary solid test brush only one unit high above it pressing against the top of this triangle. The visportal was now working yet if I removed that slim test brush and raised the visportal to the top again then it would not work. Made no sense to me unless mathematically the very top pixel of the triangle might be regarded as infinitely thin and therefore a gap. So, I left the thin test brush and gave it sky texture so it's completely invisible and everything works. | * The result might make not seem to make sense but at least if you locate the error you can try things to solve the problem. I had a visportal up to the sky and on its left against the top of a triangle of bricks on which rested a roof. The visportal seemed to be perfectly surrounded by worldspawn but I reduced it slightly with just a slim temporary solid test brush only one unit high above it pressing against the top of this triangle. The visportal was now working yet if I removed that slim test brush and raised the visportal to the top again then it would not work. Made no sense to me unless mathematically the very top pixel of the triangle might be regarded as infinitely thin and therefore a gap. So, I left the thin test brush and gave it sky texture so it's completely invisible and everything works. | ||
(Note: Some mappers at Doom3world reported that cloned visportal brushes can cause problems in a map. This was reported in an earlier Doom 3 build.) | |||
</div> | |||
== See also == | == See also == | ||
There are other good visportal tutorials to be found under: | There are other good visportal tutorials to be found under: | ||
https://iddevnet.dhewm3.org/doom3/visportals.html and https://modwiki.dhewm3.org/Visportal | |||
== Visportals, Func_statics and Worldspawn Brushes == | |||
Sometimes a visportal (VP) looks just fine in-game, but AI's behave erratically near them: cannot walk through the portal, walk into walls near the portal, can patrol through the portal but cannot chase the player through the portal. This may be due to worldspawn brushes penetrating the visportal. | |||
Image shows scenarios A-D of different VP placement. | |||
[[image:visportal_scenarios.png]] | |||
*Scenario A, when VP is snugly placed in the worldspawn corridor, it always works. | |||
*Scenario B, where a worldspawn brush penetrates the VP has often caused problems. It will fail with very high probability if the worldspawn brush is a monsterclip brush. Never do this scenario! ''[Springheel -- I'd like more confirmation on this...I'm certain I've done this on a regular basis in uneven city streets without causing any obvious problems]'' | |||
*Scenario C is what could be used if the scene absolutely requires somethings going through the VP and scenario A or D cannot be used. Usually this must be done for big outdoors VP's as seen in Knightons Manor exterior behind the manor (it is the hedge, which goes through the VP there). Note how the worldspawn brush is cut just at the VP and it is only func_static which penetrates the VP. This has worked without issues. Note that no monsterclipping is required if the func_static segment of the VP penetrating brush is short enough. The blue worldspawn brushes could also be monsterclipped func_statics as well. If so, mapper must be certain monsterclip brushes do not penetrate the VP! | |||
*Scenario D where the VP is penetrated by func_static detail work, has not been reported to break visportals. Usually this kind of case is used in vaulted corridors etc. Works just fine. If the FS detail work is in reach of AI, special care to monsterclipping should be paid and it must be absolutely sure the monsterclip does not penetrate the VP as this will always cause trouble. In this scenario it is recommended that each side of the visportal have their own func_statics and one func_static brush should never penetrate more than one visportal. | |||
===Conclusion=== | |||
Mappers should favour scenario A when possible. If detailwork requires, scenario D is okay, as well as scenario C. Never, ever use scenario B. | |||
If mapper has some issues with their AI pathfinding, they should check the portal isn't broken as in scenario B. It is really easy to forget wall trims etc which could pass through the VP. Also typical mistake is to automatically surround a model near the VP with monsterclip, which results monsterclip brush which penetrates the VP. It is recommended that the mapper tests every visportal (which an AI is likely to pass) in their map before the map is released. Firstly the mapper should check in DR and make sure visportals are correctly set. Ingame testing should be done both with non-alerted path_corner patrolling AI's and with an alerted AI chasing the player. | |||
== See also == | |||
*[https://www.youtube.com/watch?v=cy4FIE7BhCQ Komag Tutorial for The Dark Mod: Visportals] | |||
*[http://forums.thedarkmod.com/topic/18948-have-we-been-selling-visportals-short/ Have we been selling visportals short?] | |||
*[http://forums.thedarkmod.com/topic/19707-diagonaly-placed-vis-portal/ Diagonally placed visportal?] | |||
*Visportals also help delineate Location Zones, with specific ambient lighting, ambient sounds, and enter/exit script events. See [[Location Settings]]. | |||
[[Category:Skybox]] | |||
[[Category:Visportal]] | |||
{{tutorial-editing}} | {{tutorial-editing}} |
Latest revision as of 19:41, 20 October 2021
written by Fidcal. Visportals, Func_statics and Worldspawn Brushes added by Sotha.
Video Introduction to Visportals
Video Introduction to Visportals.
What are visportals?
Visportals are a very important part of mapping. They are a kind of brush that helps separate your map into individual areas (called visleafs), which is important for both rendering and sound propagation.
Without visportals, the Doom engine would render the entire map even if the player can only see one small area. This would reduce performance and slow the game down.
Visportals are also very important for sound propagation. Without them, sounds can travel through brushwork and reach areas of the map that they shouldn't (see Sound Propagation at the bottom of the page).
Visportals determine how far the engine should render from the player's position. When a visportal is in the player's view, the engine tests to see if there is a second visportal viewable from the position of the first. If yes then it tests to see if a third one can be seen from the second one. If the third is not viewable from the first then the engine won't waste time rendering the map beyond it. If it is, then the engine tests for a fourth one and so on. So for example, with a long corridor with lots of 90 degree turns in it and visportals at every bend then the engine will only render the section you are in plus any parts of the next section you can see. But as you get near to it and can see further down it to the next bend's visportal then it will render the next one too.
Anything in the visleaf that the player is currently in is rendered (if it is your field of view) regardless of whether it is behind worldspawn. But things in an adjacent visleaf will not be rendered if they are behind worldspawn. The engine still has to calculate what the player can see and what he can't, and this still uses resources, but far less than if it were in the same visleaf as the player. Any visleaf that is behind a closed portal is automatically beyond what the player can see, to the engine can skip testing it completely. This is why closed visportals are so valuable for performance. [stgatilov --- on a minor note, the engine still has to check for shadows coming out from closed visleafs; so even a closed visleaf needs some processing]
The console command r_showPortals 1 shows processed visportals as wireframe in-game for testing - even right through walls they are visible. A green wireframe is an 'open' visportal and renders everything beyond it up to the next visportal. A red wireframe is a 'closed' visportal with nothing rendered beyond it and no further visportals beyond that are even processed so are not visible at all. If a visportal does not show then it is either beyond range of processing or it is not working so check it is set up correctly.
What is rendering?
Rendering might be regarded as the calculating of surface lighting, colour, texture, etc. Not all rendered surfaces are visible in-game but still have to be calculated. Others do not need rendering at all. Processing only takes place in the current portal area, that is, up to the nearest closed visportals. Surfaces are treated as divided into triangles for rendering purposes. The r_showTris console command shows those triangles as wireframes. In the console use r_showTris N where N is...
- 0 - Off - normal gameplay with no wireframes shown.
- 1 - Shows only triangles that are visible in-game (not hidden behind other surfaces.) These visible surfaces are only part of what is rendered.
- 2 - Shows as wireframes, all triangle surfaces that would be rendered in-game. This includes those hidden behind other surfaces BUT ONLY IF they face the player, even slightly. Surfaces facing away from the player are never rendered.
- 3 - Shows as wireframes, all triangle surfaces even if not rendered.
You can see that for the purpose of testing performance use 2 above which shows all that would be rendered (whether visible to the player or not.) You can use 3 to see all triangles up to the next closed visportal but remember not all of it will be rendered so will not affect performance.
You should also use r_useScissor 0 to show geometry outside the visportal wireframe that Doom still sends to the video card.
Scissors happen on the GL driver side after geometry has already been uploaded.
They help with performance but the best performance happens when you prevent the geometry from being uploaded to your GPU in the first place.
Remember to return to r_useScissor 1 when you are done with "visportal testing" so that scissors can still
optimize away geometry that you were unable to optimize away with visportals.
Here is a short video with a decent visual breakdown:
Another video:
How and where to create visportals
Visportals are just brushes with one face covered in visportal texture. That is the operative face. Only be concerned with that one surface as the rest of the brush merely carries it. So to create one you just....
- Make a thin brush like a wall. Ideally make it rectangular for best sound propagation (see Sound Propagation later.) It can extend beyond the gap so does not necessarily need to be the same shape - see Where to place your Visportal later.
- Give it textures > editor > visportal to either of the main surfaces facing towards or away from you. It does not matter which except you need to be aware which it is because the visportal will be effective at that one face. (Use Ctrl + Shift + on the face in the Dark Radiant camera view to select one face.)
Thickness
The exact thickness is not important to its effectiveness as it will only be effective from its one visportal-textured face anyway but it makes sense to keep it reasonably thin so you can see it clearly in the editor. Always think of visportals as one flat face and the rest of the brush can be ignored for functional purposes.
Where to place your Visportal
It will eventually be wedged tight like a plug into gaps, doorways, etc. between areas. The edges of the visportal-textured face of visportals should be completely sealed by or in opaque (i.e. solid) worldspawn brush that has no gaps. The brush must be a child of worldspawn and not an entity. This is true even if the visportal is within a door (see next section.) For the visportal to be effective it does not matter if the rest of the visportal brush sticks out into space so long as the edges of the visportal-textured face are surrounded by worldspawn brush and/or another visportal brush (see later) In practice you will probably put most fully within a corridor or doorway, a city street (yes, the sky above is solid worldspawn brush), etc. Irregular shaped gaps must still be plugged with a rectangular visportal which should then overlap into the solid worldspawn and leave no gaps. This will also make sound propagation work correctly (see Sound Propagation later.)
Each area you thus created must be totally enclosed with worldspawn brushes with no gaps of either space else an entity. So a closed building with visportals at the doors but a tiny gap under the eaves of the roof won't work! Also avoid only blocking gaps with entities whether brushes or models. For example, a two-sided window entity that completely fills the opening will not seal the area for portalling purposes. Do not put in a visportal unless the window is either transparent or can be opened (like a door.) Instead put in a worldspawn brush with nodraw texture on it so it will not be visible or collidable just in front of the window. [not sure what this means, but note that nodraw textures DO NOT seal visleafs. As far as visportals are concerned, they don't exist] Or if you are using two windows back to back (say a lit one outside and an unlit one inside then a thin caulk brush between them.
Generally you will place visportals on bends in the terrain around which the player cannot see from the current viewpoint. Avoid placing visportals in a line along a corridor or street for example. Since the player can see straight down through them all then they serve no purpose as they will all be open and visportals themselves create extra triangles and complexity (see downside section below.)
With a large building surrounded by a walled open area then try visportals at each corner. If it is a very large building then also add visportals midway along each side. The player standing at one corner might be able to see up two sides, part of a far side, and even a small part of the fourth side so all sides would be rendered. By having extra visportals middway along each side then at least half of each side of the furthest corner need not be rendered (consider also preventing the player reaching such a viewpoint with an obstruction!)
Subject to the above, try to find the smallest gaps where possible to place visportals. The smaller the visportal then the smaller the view aperture and so the less chance of lining up those apertures. Remember, visportals beyond the first one do not open unless they intersect all open visportals in that line of view. Even without a door, an open doorway is a better place for a visportal than a wider corridor or room beyond. Imagine trying to get a straight pole through as many of these visportal apertures as possible; the narrower and less aligned they are then the harder to get the pole very far.
Don't get too hung up on perfect placement of every last visportal. Generally if you follow this guide and use your judgement you achieve a satisfactory game performance. Examine some large maps that you know work well to get some ideas where visportals are placed using the r_showPortals 1 command.
What if you put visportal texture on many faces of the visportal brush? Only one arbitrarily chosen face will be effective, and dmap will produce console warning about this situation. Basically, the engine does not support such brushes, so better use nodraw on all surfaces except the one face with visportal texture.
Multiple Joined Visportals
Because visportals are a single face, by their very nature they can only be placed on a single brush. But visportal brushes can be placed or merged together to fill more complex shaped gaps. For example, a wide rectangle might have one side clipped to slope over a roof while the rectangular part of its shape sits on top of another rectangle across the street below. But complexity affects performance so only do this if one rectangular visportal intruding into interior walls might do the same job. Remember, it does not matter if the visportal overlaps into solid so if there is an interior wall on the same plane (or indeed if the building is totally solid) then the visportal can penetrate it and still function. Do not use multiple visportals just to shape nicely around solid building trim and structure but intrude into it so long as the edge does not exit into space at any point it will be fine.
Visportals and doors
A visportal in contact with a door that has an openable property automatically becomes "blocking" when the door is closed. Blocking visportals are always considered closed. In fact, they provide additional performance benefit over ordinary (i.e. nonblocking) closed visportals. For instance, objects behind ordinary closed visportals can still throw shadows which are visible to the player, so the engine has to process them. But blocking visportals block everything including light and shadows, so the renderer skips all visleafs behind them even when looking for shadow casters.
Of course, when you open a closed door, its visportal becomes nonblocking/ordinary again, and switches between open and closed state as usual. So when you first go through a door and leave it open then its visportal will be open as you look immediately back at it. But as you then proceed further through other visportals, the door visportal will eventually close (prevent rendering through it) even if the door itself is left open.
Doors standing in front of but not within a doorway
Note that the visportal only needs to be in contact with the door to be affected by it. Normally you would place the visportal within the door but it actually only needs its visportal-textured surface to touch it. This means that if you have a door that is stood in front of an opening in a wall then you cannot put the visportal inside the door because it will not be surrounded by solid brush. But you can put a visportal just inside the opening and flush with the mouth of the opening and the door immediately in front of that and in contact with the visportal. You can test this by placing the door offset well to one side but part of it still in contact with the visportal. In game you can see the opening as the door is only partially covering it. When the door is closed the visportal closes and stops rendering through the doorway. You will see this as a black panel in the doorway. As the door opens the black panel disappears and you can see through the doorway again. You might think that from the other side the black panel would obscure the door when closed but it doesn't. With the door centred in its normal position, typically you might have an entity frame around the door. If you had a solid brush frame without gaps then the visportal could be inside the door if you wanted as it would then have solid all round its edges. In many cases of course, the door frame, whether entity or brush, would be within the solid brush doorway anyway.
Geep comments: This is pertinent for surface-mounted sliding doors. Unless they include transparency, such as ductwork grill doors (whether sliding or rotating), in which case the next section rules.
Windows, Doors with windows, bars, etc.
Openable doors that let you see through them such as windows, doors with windows, barred gates, etc. should not be in contact with a visportal. When the door is closed it will automatically close any visportal whose effective surface is in touch with it. The visportal will not then permit any rendering through it and will show as a black panel in the window or between the bars of a gate. Instead, move the visportal away from the door. It will still function effectively as a normal visportal just as if the door were not there. This does not of course apply to simulated windows such as a glazed textured panel on a door texture where you cannot actually see through.
All doors and windows that do not have an openable property can have a visportal in touch with them as it will not be affected by them and it will just function as a normal visportal.
Rev. 2.00:
Starting with Rev. 2.00, you can touch a see-through door or window with a visportal, and the portal will not close when the door/window is closed, as long as you use the following spawnarg on the door/window (not the info_portalsettings entity):
- transparent "If set to 1 (0 by default), a see-through door can touch a visportal and the visportal won't close when the door is closed."
This is useful when you want the opening or closing of the door to affect the sound loss across the portal, but not affect visibility through the door/window. Imagine a closed window that muffles a sound beyond it, and as the window opens, the sound gets louder.
Visportal switches: func_portals
The preceding section Visportals and doors makes clear that doors can function like switches to enable and close visportals in contact with them. func_portals can be used to enact further control over portals. You can place a func_portal entity so that it intersects with a visportal, and then trigger the func_portal to close or open the visportal. A second control method is had by using the portal_dist and distcheck_period properties on the func_portal. They control the distance to the player and how frequently (in seconds) this distance should be checked, respectively, and make explicit triggering of the func_portal unnecessary. As with doors, even if enabled, the visportal will not be open even if it is in the player's view. Note, if you have a mover (door/window) in contact with the visportal, it will affect it as well, so typically a visportal controlled by func_portal is placed away from the mover, or use spawnarg "transparent" set to 1.
Another clever trick exists with regard to func_portals: you can also build a func_static over the visportal, and target it with the func_portal as normal. Now, in addition to opening and closing the portal, this will also toggle the drawing of the func_static. This means you could place an appropriate texture (perhaps a low resolution image of a room's interior, drawn over a window) and have it turn on or off based on the player's distance away. From a distance, the player wouldn't be able to tell that the the entire room wasn't being rendered. This can be an effective way to create the illusion of long view distances.
Note that the func_static must touch the visportal in order to work.
One way to make this work is to create a patch, make it a func_static. Texture the patch, and then target the func_portal at that func_static. You must then add "hide" "1" to the func_static patch. There may be other ways to make this work, but I had a lot of trouble until I took these steps. -- Springheel
An interesting, recent discovery that needs some testing is that apparently: you can take one visportal and cut it in half, and then put different func_portals on each half in order to close them at different ranges. That has interesting implications for wide city streets. They require big visportals, but if you can split them up and independently control each part, there may be some benefits there. http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/?p=370473
Need I design, even compromise my map to make best use of visportals?
You need to design your map from the start as a series of connected boxes (brushes) with the player's view, sound propogation, and visportals in mind. And yes, sometimes you might need to add a bend you don't want or obstruct a view in some way so you can put in another visportal if you are having or expecting slow down in a large and/or complex area. This is a matter of experience. If you have large complex areas and are experiencing frame lag but can see no obvious place to put a visportal then you might need to compromise your terrain and add some solid brush barriers to block certain views with visportals in the access round or through them.
Note that it is not essential that visportals be only at the actual joins between brushes; they still work even if they are half way down a corridor so long as they are wedged in tight without gaps. But you will mostly place them at joins.
For rendering considerations, the player's view is everything and every room and street in front of you even if there are walls, etc. in the way. Imagine what you would see with X-Ray vision. What is behind you or just out of range of the screen does not matter. But visportals restrict the view to what can be seen through the aperture of the visportal.
It is not necessary to put visportals at every tiny bend in the map; in fact that should be avoided in smaller areas because visportals themselves create extra triangles and complexity (see downside section below.) Try to keep in mind what will be rendered through the visportals and judge what would not cause frame lag slowdown if the player could actually see that view. Three or four bends without visportals in a restricted air duct is not going to cause any problem if the duct is correctly visportalled at the ends for example.
Is there a downside?
One downside to visportals is that is extra work for the mapper! Another is that they split the geometry and create extra triangles and batches. This will not normally cause a problem unless your map has a very large number of areas. The advantages in performance of using visportals far outweigh the downsides!
Sound Propagation
Correct propagation of sound (both to AI and to the player) relies on visportals.
Think of vis-portals as sealing off separate "areas" in a map. A sound that occurs inside a sealed "area" will travel in a straight line to anyone inside the same area, even through walls. If you are not in the same area, however, the sound will travel in a straight line to the first visportal between you and the sound source, then to the next one, etc, until it reaches the area you are in.
If the sound happens in an area that is not sealed, it essentially considers the whole map its "area", and will go straight to the player, through walls, floors, or other brushwork. This can result in confusion for players, as they will hear AI on the other side of a massive wall as if they were standing beside each other.
In the following examples, "P" is the player and "S" is the sound source. The Visportals are red lines. The green lines show how the sound would travel.
Without any visportals, the sound goes in a straight line to the player, even through solid walls. It will sound like the player is in the same room as the sound.
One visportal is an improvement--it will sound further away, but the sound travels straight to the visportal and then straight to the player, so it will still sound like it is coming through the wall.
Two visportals are best in this case, however. The sound will seem like it is coming from the opening to the room, which is where you would expect it to come from.
Sound going to the AI travels the shortest distance through a visportal, passing at any point on the visportal surface. Mappers should always use rectangular visportals unless you have no choice with an awkwardly shaped gap or if the gap is out of range of AI, for example along a sloping roof where AI never go. It also still assumes that when you do have four sides, they are perpendicular. If you have some non-90 degree angles between the sides, some wierdness may ensue. For example, an AI that is alerted in the dark (or facing away) by hearing a sound from the player that passes through an irregular visportal might run to the center of the visportal rather than directly to where the player made the noise. Irregular visportals large enough to make this effect noticeable are likely to be uncommon.
This will be okay for smaller irregular visportals, but the error (path difference from the minimal path) will get more noticeable the larger the visportal.
Visportals function individually even if joined together into complex shapes. So a rectangle at ground level topped by an angled visportal above it tilting out over a roof will be treated separately, not as one aperture.
The bottom line is, with any non-rectangular visportals keep the above in mind and if in doubt then consider early testing of AI's alert to player sound.
Visportals do NOT need to be closed to correctly channel sound to the player. Sometimes it is worth adding visportals even if they will not help with rendering (because they will always be open) in order to make sound travel the way it should.
To make less sound go through a visportal (through a small hole, for example): Soundprop can use info_locationSeparator or info_portalSettings to make sound incur a certain loss when going through the portal it's touching. The key/value pair is the following:
sound_loss "Soundprop: Loss in dB incurred when a sound travels through this portal. Cumulative with door loss if a door is present."
The loss must be a positive number, and negative numbers will automatically be converted to positive.
Rev 2.00:
Prior to Rev 2.00, sound_loss affected the sound propagation to AI only. Sound propagation to the player was not affected.
Starting with Rev 2.00, sound_loss is also used in determining sound volume to the player. This aligns what AI hear with what the player hears. It also allows sound coming through the door to increase as the door opens, or decrease as the door closes, making for a more realistic experience.
For details study: Sound Propagation: Part 1 and Sound Propagation: Part 2
Engine changes
Several bugs in dmap related to visportals were fixed in TDM 2.08. The technical description is provided in issue #5129. Here is the rough summary:
- Normally, leaky visportals should be dropped by dmap, but a lot of them actually made it into the final maps. As a rule of thumb, a few dozens of functioning visportals in every FM released so far are leaky. Most of them cause no serious issues, although some of them cause thin black stripes where they leak. The new dmap drops all leaky visportals without exceptions. It means that if you compile an old FM with the new dmap, a lot of visportals will be lost.
- A visportal had some weird effects outside of its bounds on its plane. This caused terrible trouble when several visportals lied on the same plane. Aside from that, it could produce ugly black panels on places without any visportals. All of this is now fixed, but there is a chance that some existing map somehow relied on the old erratic behavior.
- Normally, if a brush has at least one non-opaque side (i.e. non-solid face), then it is considered non-opaque and does not seal visportals and areas. A bug caused some brushes with exactly one non-opaque side to be considered opaque. It is now fixed, but as the result some rare brushes on existing maps no longer seal areas if you dmap them with recent engine. This can lead to global leaks and dropped visportals.
The changes seriously affect how visportalling works on existing maps. If you need to dmap an FM which was released before 2.08, then you have a choice:
- Fix all the visportal warnings which dmap spits to console (see the next section). This will take some time and effort, and will probably need additional beta testing after that.
- Enable old and buggy behavior of visportals, so that dmap works exactly as it did when FM was released. To achieve this, you have to set the following cvars (note that they do not persist between sessions):
- dmap_bspAllSidesOfVisportal 0
- dmap_fixVisportalOutOfBoundaryEffects 0
- dmap_fixBrushOpacityFirstSide 0
Troubleshooting
Starting from TDM 2.08, dmap provides several useful diagnostics for visportalling problems. Every visportal with a problem is reported to the game console as a warning. You might want to enable logFile to make it easier to read the whole dmap output. Aside from that, most warnings are accompanied by .lin files (generated near your .map), which can be viewed in DR. Below you can see the different types of warnings produced by dmap.
- Portal %d at (%s) dropped
- The mentioned visportal does not separate the space into two isolated areas. This is usually called "internal leak". Such visportal is dropped because it appears to be fully contained in one visleaf, while every visportal must separate two different visleafs from each other.
- Remember, the visportal face must be surrounded by opaque worldspawn brushes. Entities have no effect on visportals and visleafs, and brushes with any nodraw material are also ignored. If brief inspection does not help, load the .lin file in DR: it shows a closed path passing through the visportal which is not blocked by anything. In order to make visportal functional, you must block this path at least somewhere: the exact understanding of what went wrong and how to fix it is up to you.
- Portal %d at (%s) dropped as leaky
- This is popular subcase of "dropped" warning, implemented in TDM 2.10.
- A proper visportal must have all of its boundary edges fully in contact with opaque geometry or other visportals. You should see "as leaky" clarification when this rule is broken.
- To fix the visportal, inspect its boundary, i.e. where it touches solid geometry.
- TIPS: If you have any portals "dropped as leaky", save yourself some time by correcting them first. This will often stop other (good) visportals from being dropped. The .lin file discussed below will often show you exactly where the boundary problem is. Be aware that occasionally you may find a "dropped" portal that should have been tagged "dropped as leaky"; the detection algorithm is approximate.
- Portals [%s] at (%s) overlap
- Two or more visportals geometrically overlap, which is going to be confuse the engine. In most cases the offending visportals are exactly equal, which is why it is very hard to notice without warning. Note that it is OK for visportals to touch each other.
- In order to fix the problem, find both visportals in DR, and probably just delete one of them.
- Portal %d at (%s) is useless
- No part of this visportal is within the playable space. Sometimes such visportal is fully inside opaque brushes or lie on the boundary of opaque brush. Sometimes the whole visportal hangs somewhere in outer space, outside of any playable locations.
- Find this visportal in DR, verify that it is not necessary, and delete it.
- brush %d has multiple area portal sides at %s
- More than one side/face of this brush is marked with visportal texture, which is not supported by engine. Remember that visportal brush must have exactly one face with visportal texture and all the other faces with nodraw texture.
- First, find the brush. If any face has visportal material by mistake, change it to nodraw material. If both sides should work as visportals, then split the brush into two, each with one visportalled face.
When investigating a particular warning, there are several ways to find and debug the visportal.
- The brush number of the problematic portal is reported in the warning itself (like: Portal 5237). You can quickly find the brush in DR by using "Map -> Find Brush" feature, setting "Entity Number" to 0. Beware that brush numbering changes when you modify the map. If the numbers lead you to non-visportal brushes, then you most likely need to rerun dmap to get the new numbers.
- The warning usually contains world 3D coordinates (like: at (347.25 -490 790)). These coordinates are much more stable that brush numbers and won't change between runs. You can use setviewpos in-game to teleport to specified coordinates, and hopefully DR will have such feature too in future.
- For every dropped or overlapped visportal, a leakfile is dumped into a .lin file. The filename is reported right after the warning itself (like: saved mapname_portalL_coords.lin (%i points). The capital letter after the word "portal" indicates the type of problem (e.g., with TDM 2.08, O = Overlap, L = dropped/Leaked; with TDM 2.10, O = Overlapped, D = Dropped, L = dropped as Leaky). The file is located in the same directory where .map file is located. In order to open it in DR, use the File → Pointfile menu option, which will show a dialog allowing you to choose the appropriate .lin file if there is more than one available. Use View → Camera → Next/Previous leak spot (or respectively Ctrl+Shift+K and Ctrl+Shift+L) to teleport to leak location and travel along its points. Fly around: follow the path, see where it crosses something that you considered opaque while it is not.
If you have fixed all warnings but some visportal doesn't work at all (i.e. does not show as either red or green while you are directly in its area and looking at it and you have r_showPortals enabled), then make sure the visportal is worldspawn, not some entity with a misapplied visportal texture.
Expand the section below to read some outdated information. It is useless starting from 2.08.
There are two possible problems I can think of: the visportal doesn't work at all or it works yet there is too much being rendered giving poor performance and frame lag. The latter problem is a matter of experience and experimentation. Often much ingenuity is needed to place visportals to reduce the size of areas being rendered at any one time. There is probably a different solution for every situation. Ultimately you might be forced to change the terrain to help visportalling.
If a visportal doesn't work at all (eg, does not show as either red or green while you are directly in its area and looking at it and you have r_showPortals enabled) then that means there is a "leak" in that area. It does not necessarily mean the visportal itself is the problem.
Try the following to track down the problem.
Check the visportal itself:
- Check which face of the visportal is facing which way. It sometimes happen one clones a visportal and rotates it the wrong way without realizing. So the wrong face is in the right place but the visportal face is not in contact with worldspawn.
- Make sure the visportal hasn't been assigned to an entity but is worldspawn.
- Search for gaps anywhere around the edges of the visportal face. Check for grid snapping not only of the visportal but the surrounding brushes. A tiny difference might not be visible in the Dark Radiant grid if you are not zoomed in sufficiently.
- Check all surrounding items to see if any are entities. Remember, the visportal face must only be surrounded by worldspawn brushes. It seems to be mostly OK if the visportal cuts through an entity so long as it meets worldspawn at its edges.
Check the area for internal leaks:
There is a way to test an individual area for leaks. It sounds more complicated than it is.
1. Filter off all entities. Make sure visportals are NOT filtered.
2. Select your entire visible map (which will now be only brushwork).
3. Copy and paste into a new blank map.
4. Put the player start into the area where you think you have an internal leak.
5. Take the visportals sealing that area and texture them with a solid texture.
6. Make sure there is only void around the map (if you have your entire map encased in a skybox brush, open a hole in a distant corner of the map).
7. Save the map as a new filename and run dmap. If you do not get a leak, then the area with the player start is properly sealed. Move the player start to a new area and repeat as needed.
8. If you do get a leak, open the pointfile in DR. Because the player entity is the only entity in the map, the red line will always start there and will show you where the gap is.
9. Go back to your original map and fix the gap. Repeat as needed.
Having visportals that line up in parallel with each other can cause problems, usually appearing as pieces of wall that appear black or show skybox. This can usually be fixed by moving a visportal slightly or turning one on a slight angle so they're no longer parallel.
If all else fails, try:
- Clone the visportal and drag one edge to one side, that is, reduce its size to say half.
- Select the original and drag its opposite edge the other way so you now have two visportals pressed together and which together fill the gap. Guess which side unless you suspect one side particularly (see later.)
- Change one of the visportals to any normal visible simple texture, stone, wood, whatever so that now the original gap is smaller and filled by just one smaller visportal. (with hindsight, I think this would probably work anyway and might even be better just leaving it as visportal so you can see which one works but I'll continue with what I did!)
- Check it in game.
- If it still does not work then reduce it further, perhaps by half as much again. In particular, go past edges of surrounding brushes (eg, if working downwards with two brushes on the left then maybe it's the top brush that is the problem so reduce the top of the visportal below its bottom edge.) Obviously as you reduce the visportal you increase the solid temporary brush you made equally to keep up so there is never a gap.
- If the visportal still does not work even when reduced to a slither then try the same for all four sides noting that the three sides against the slither of visportal are obviously first suspects.
- If eventually the visportal starts to work then you know the error is in the other section where you have the solid temporary brush. Use a process of elimination to track down exactly where the error is.
- You might even have to create a third temporary brush or even a fourth but you must eventually force the visportal to work even if you surround it with four new brushes! Once working, then reduce, remove, gradually until the error re-appears - that must be where the error lies. So by a process of elimination you should track down the source of the problem.
- The result might make not seem to make sense but at least if you locate the error you can try things to solve the problem. I had a visportal up to the sky and on its left against the top of a triangle of bricks on which rested a roof. The visportal seemed to be perfectly surrounded by worldspawn but I reduced it slightly with just a slim temporary solid test brush only one unit high above it pressing against the top of this triangle. The visportal was now working yet if I removed that slim test brush and raised the visportal to the top again then it would not work. Made no sense to me unless mathematically the very top pixel of the triangle might be regarded as infinitely thin and therefore a gap. So, I left the thin test brush and gave it sky texture so it's completely invisible and everything works.
(Note: Some mappers at Doom3world reported that cloned visportal brushes can cause problems in a map. This was reported in an earlier Doom 3 build.)
See also
There are other good visportal tutorials to be found under: https://iddevnet.dhewm3.org/doom3/visportals.html and https://modwiki.dhewm3.org/Visportal
Visportals, Func_statics and Worldspawn Brushes
Sometimes a visportal (VP) looks just fine in-game, but AI's behave erratically near them: cannot walk through the portal, walk into walls near the portal, can patrol through the portal but cannot chase the player through the portal. This may be due to worldspawn brushes penetrating the visportal.
Image shows scenarios A-D of different VP placement.
- Scenario A, when VP is snugly placed in the worldspawn corridor, it always works.
- Scenario B, where a worldspawn brush penetrates the VP has often caused problems. It will fail with very high probability if the worldspawn brush is a monsterclip brush. Never do this scenario! [Springheel -- I'd like more confirmation on this...I'm certain I've done this on a regular basis in uneven city streets without causing any obvious problems]
- Scenario C is what could be used if the scene absolutely requires somethings going through the VP and scenario A or D cannot be used. Usually this must be done for big outdoors VP's as seen in Knightons Manor exterior behind the manor (it is the hedge, which goes through the VP there). Note how the worldspawn brush is cut just at the VP and it is only func_static which penetrates the VP. This has worked without issues. Note that no monsterclipping is required if the func_static segment of the VP penetrating brush is short enough. The blue worldspawn brushes could also be monsterclipped func_statics as well. If so, mapper must be certain monsterclip brushes do not penetrate the VP!
- Scenario D where the VP is penetrated by func_static detail work, has not been reported to break visportals. Usually this kind of case is used in vaulted corridors etc. Works just fine. If the FS detail work is in reach of AI, special care to monsterclipping should be paid and it must be absolutely sure the monsterclip does not penetrate the VP as this will always cause trouble. In this scenario it is recommended that each side of the visportal have their own func_statics and one func_static brush should never penetrate more than one visportal.
Conclusion
Mappers should favour scenario A when possible. If detailwork requires, scenario D is okay, as well as scenario C. Never, ever use scenario B.
If mapper has some issues with their AI pathfinding, they should check the portal isn't broken as in scenario B. It is really easy to forget wall trims etc which could pass through the VP. Also typical mistake is to automatically surround a model near the VP with monsterclip, which results monsterclip brush which penetrates the VP. It is recommended that the mapper tests every visportal (which an AI is likely to pass) in their map before the map is released. Firstly the mapper should check in DR and make sure visportals are correctly set. Ingame testing should be done both with non-alerted path_corner patrolling AI's and with an alerted AI chasing the player.
See also
- Komag Tutorial for The Dark Mod: Visportals
- Have we been selling visportals short?
- Diagonally placed visportal?
- Visportals also help delineate Location Zones, with specific ambient lighting, ambient sounds, and enter/exit script events. See Location Settings.