Making DOOM 3 Mods : Vis Portals
Here is a simple donut map 8 portals in it. When this level is compiled, it creates 8 areas. Those areas are numbered 1-8 in the screenshot below.

When Doom 3 renders the level, it first renders the area the view is in then it flows through all visible portals rendering each area it encounters. In this example, it would render area 3, then it would render areas 2 and 5, then areas 1 and 8, then maybe areas 4 and 7.

If a level has no vis portals in it, there is only one area so the entire level is rendered every frame.

The renderer determines visibility between areas by doing unions of the screen space rectangles between the areas. The following in-game screenshots should make that statement a little easier to understand.




Walls

Notice how the renderer only uses the portals for determining visibility, it does not use geometry at all. If you have a wall in between two portals, it will still render what's on the other side of the wall unless there is another portal in between to divide the room into two areas.

Doors

If a vis portal is placed inside a door, the door will automatically close the portal when the door is closed. You can do the same thing manually through func_portal entities (these are handy for complex doors like airlocks).

Batches

The downside to portals is that they create extra triangles and extra batches. Video cards are set up to handle a small number of batches with a large number of triangles per batch. All the triangles in a single area with the same texture are put into a batch. When you create a vis portal, it splits the geometry, and adds more batches. This is normally not a problem unless you have a lot of areas with only a hand full of triangles in them.

Testing

To test the visibility in your own map, use the following cvars:

r_showTris 2
r_useScissor 0
r_showPortals 1

Scissors

To further improve rendering speeds, the Doom 3 engine utilized scissors when rendering areas through a portal. These scissors prevent geometry outside the portal rectangle from being drawn by the video card. This is not a magic cure however, because the data is still being sent to the video card, it's just that the video card is ignoring it.

If you do not set r_useScissor 0 then you will not see the full extents of what is being rendered. You will only see what the video card is actually drawing. Remember, just because your video card is throwing away the geometry doesn't mean it's free. Your CPU still has to waste time sending the data to the video card. This is a very slow process. You don't want your computer to waste time sending a lot of data to the graphics card just to have it thrown away.

Here is the same scene with scissors enabled:

Remember, always test your portals with scissors disabled!

Copyright © 2004 id software