generating sectors from geometry and portals

As far as I understand Doom 3 is using a portal based renderer. But in the map files there is no information regarding sectors, there are only brushes (=geometry) and visportals (actually just brushes with a special texture).

Does anyone know how to find a set of portal connected sectors from just this data? How does Doom 3 do this?

I’m not sure I understand your question. I know of 3 ways to use portals in rendering:

  1. Leaf portals: front to back traversal, clip to each leaf portal along the way. I don’t think anyone is using this approach anymore.

  2. Zone or Cluster portals: Same as 1, except clipping/occlusion takes place at the cluster level. I think the Unreal engine uses this approach.

  3. Precalculated portal vis: All leaf visibility calculated up front. Runtime visibility is determined by a leaf/cluster table lookup. This is the fabulous method that Quake made famous.

I suspect Doom3 is using precalculated vis tables, but I’m not certain of that. I haven’t looked at the Doom3 stuff, so I can’t say for certain. In any case, given the map BSP or original map data, you should be able to derive what you need to implement any method you like.

Afaik, Doom 3 does not precompute visibility. Doom 3 doesn’ use .bsp-files like Quake did, it uses .map files directly.

I don’t know any details, but I know for sure:

  • Clipping/occlusion happens at runtime, that means sectors behing a portal are only visible if the portal is visible. You can verify this by turning on wireframe rendering.

  • In the map file you have to place “visportals” to seperate different zones, but there is no zone information in the map files, only geometry and portals (the map files are plain text, its very easy to verify this).

I think that Doom 3 uses your option 2, or something completely different I haven’t figured out yet.

My problem is: For Option 2 to work I need information which geometry is in which zone. But I don’t need it at runtime, a preprocessing stage is fine too.

After I have the zones, I know how to calculate the visibility, but I don’t know how to calculate the zones…

EDIT: After some more research, I found the information I am looking for. It is actually generated by the editor in a seperate file with extension .proc. But I still want to know how to generate this information, because I don’t want to be dependant on the Doom 3 editor.

Well, to generate zones in a BSP, you need all the node and user defined portals, complete with front/back leaf information. If all you have is raw geometry, then you’ll likely need to start at the beginning.

Assuming you have all this stuff, you can find the zones as follows:

findZones() {

for( all leaves L that have no zone number yet )
{
    zoneFill( L );
    currentZoneNumber++;
} 
}
 
zoneFill(Leaf L) {
 
if( L.zone )
   return;
 
L.zone = currentZoneNumber;
for( each portal P in L )
    if( P is NOT a zone portal )
       zoneFill( P.leaf );

}

The basic idea is to flood fill from a given leaf (doesn’t matter which one). The fill is blocked only by zone portals. Assuming the tree is watertight, this should assign a zone ID to each leaf encountered.

But without the leaf info for the portals, I don’t know what to say; there could be a problem.

By the way, I like option 2 as well, especially with SLI/PCIE around the corner :slight_smile:

Interesting idea. If I understood it correctly I have to generate a bsp tree and get zone/portal information out of it, then I merge these small zones to larger ones…

This way I could treat user placed portals as normal geometry while generating the bsp tree and just merge all bsp leaves that are connected into zones, and finally connect these zones using the portals…

I need to do a bit more research on this, I’ll post the results when I have something…

Thanks for the suggestion

Interesting idea. If I understood it correctly I have to generate a bsp tree and get zone/portal information out of it, then I merge these small zones to larger ones…
Yes, build a BSP and portalize it, adding user defined portals (zone-portals) during portalization. In the end, each portal, zone or node, should have a pointer to the leaf it faces. This allows you to visit each leaf in the world by just walking through all the portals.

This way I could treat user placed portals as normal geometry while generating the bsp tree and just merge all bsp leaves that are connected into zones, and finally connect these zones using the portals…
Exactly. However, there are a few caveats. For instance, when a zone-portal is in the plane of a node portal, a choice has to be made regarding precedence. I always say that zone-portals eat node-portals. This may not be an issue in the case of Doom3, if all you’re after is portal visibility. But clearly the visible zone-portal extents need to be preserved.

*--------------------*--------------------*
|                    '                    |
|         C          'Node portal         |
|                    '                    |
*--------------------*                    |
                     |                    |
                   P |         A          |
                     |                    |
*--------------------*                    |
|                    '                    |
|                    '                    |
|         B          'Zone portal         |
|                    '                    |
|                    '                    |
*--------------------*--------------------*

The user wants to make room B a zone, but it just so happens that the portal falls on the node created by plane P. In this case, the zone portal wins in leaf B. Some cases are not so clear cut. This is especially so if the user is given the freedom to add portals indiscriminately. You might need to allow for the possibility of partial node coverage, and so on.