[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.6.7.8 Potentially Visible Set (PVS)

The c-buffer is a very good way to manage real-time visibility. i.e. there is no precalculation involved (except for the octree). However it is a reasonably high overhead since it involves transformation to camera space, perspective projection, and scan converting every polygon.

We already presented ways to reduce the overhead by limiting c-buffer filling to world geometry and culling objects only. But this may not be enough.

So we present another way to reduce this overhead. This is a PVS or Potentially Visible Set. Basicly for every octree leaf in the octree we keep a set of all other visible nodes and polygons. Before testing a polygon or node against the c-buffer we will first see if it is in the PVS of the current leaf where the camera is. If it is not then we don't need to continue testing. This means we can avoid having to transform, perspective project, and scan convert the polygon and then test to the c-buffer. This can be a huge benefit.

After doing the PVS test we have two choices basicly. We can still decide to use the c-buffer to do finer culling tests. The PVS only provides region to region visibility. It is possible that less is visible from within some point in some region. Whether or not it is really worth it to cull further is again something which we'll have to test. For the software renderer it will probably be worthwhile because overdraw is so expensive there. On the other hand it can still be useful to use the c-buffer in order to be able to cull complex detail objects.

Static detail objects (detail objects that cannot move) could also be included in the PVS easily.

Calculating the PVS

Calculating the PVS is a complex and time consuming task in itself. Currently this is not yet implemented. The approach that is probably going to be used works as follows.

We traverse every leaf of the octree (ignore BSP nodes and leaves). For every such leaf we want to build the PVS. So we again traverse the octree for every other node this time. We are going to test visibility between the leaf and every other node (called occludee). When we find that some occludee is not visible we don't have to continue to the children. They will not be visible either.

So for a given leaf and occludee we initialize a cube of c-buffers (or some other 2D visibility system like the coverage mask tree). On this cube we are going to paint all shadows that are caused by occluders between the leaf and occludee.

So we then again traverse the octree to find all potential occluders. An occluder will be considered if it is between the leaf and the occludee. The algorithm works as if the occludee is an area light source. We will take all the polygons of an occluder and cast shadows from the light source on the cube surrounding the leaf. If eventually the cube is entirely shadowed by the collected polygons in all potential occluders then we say that the occludee is not visible from within the leaf. So we don't add it to the PVS.

An optimization here is that when an occluder already has a calculated PVS then we can see if the occludee is visible for the occluder. If not then the occluder can be seen as a solid box from the viewpoint of the leaf for the occludee and we can cast a shadow from the entire box at once.

This is the basic algorithm. More detail will follow later (about the PVS for polygons and so on).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html