Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.


  • Loggen Sie sich ein, um Kommentare anzuzeigen.

  • Gehören Sie zu den Ersten, denen das gefällt!


  1. 1. BSP Trees in 3D Game Engines (2) Shot from Unreal Tournament 2003 Shot From Doom3 Modified from an original presentation prepared by Jason Calvert, 2003. Principles of: Portals and Potential Visibility Sets (PVS)
  2. 2. Intro to PVS We need to know which other leaves can be seen from any one leaf. A PVS is a 2D array of bytes or booleans which contains all visibility info for each leaf. Each leaf's visibility information is a single row - one column for each other leaf. If the 3rd entry in the row representing leaf 2 is true then leaf 2 can be seen from leaf 3. Thus, this array will tell us which leafs are visible from any other leaf. The PVS is non view dependent. It just tells us what is potentially visible even if it’s outside of the frustum.
  3. 3. Building a PVS There are two steps to building a PVS. Portal Generation. Finding out information about the gaps( doorways) in our level. Anti-Penumbra clipping. Testing which leafs are visible based on the portals.
  4. 4. Portals A portal is a special polygon that lies on one splitting plane of the BSP tree. Some portals will define non-solid boundaries between adjacent leaves. A portal between two leaves says that there is a non-solid boundary between the leaves and thus,one leaf is potentially visible from the other.
  5. 5. Portal Based Engines In a strictly portal based engine, portals will be used in visibility processing between sectors (subsections of a level). In these situations visibility is determined at render time, not from a pre-calculated PVS since visibility is dependant on camera position. Only render what can be seen from camera through a portal. Process runs recursively until no more portals can be seen through the current portal. Ideal for mirrors. Build a frustum from camera to portal and flip it so its pointed back at you.
  6. 6. BSP and Portals In Leafy BSP trees we will also use portals for visibility processing, but as a compile time step. Portals will be used to construct the PVS for a level but they will not be used at render time. Portals will tell us the area of the gaps or doorways in our level.
  7. 7. Building Portals Some engines force you to place portals by hand. This requires more work in the level editor but less time is required to compile the level (build BSP tree). We will use our BSP tree with polygon splitting to build these portals. Build process is similar to the bsp compile process.
  8. 8. Portal Building Process Start by building a large polygon at each node in the BSP tree. This polygon is a portal that will lie on the node's splitting plane. Each portal polygon will receive a unique ID value that can be used to identify the portal after it ends up in a leaf node. Send portal polygon down the tree starting at the node it is built from.
  9. 9. Portal Building Process (2) As it descends the tree classify the portal polygon against the current node's plane. If portal polygon is in front of the splitting plane and not at a leaf send the portal polygon down the front of the tree. If the front is a leaf, this portal polygon is in empty space and will be potentially used. If portal polygon is behind the plane and not at a leaf send the portal down the back of the tree. If we are at a leaf this portal is in solid space and can be rejected.
  10. 10. Portal Building Process(3) If the portal polygon is spanning the plane it must be split. The front section will go down the front of the tree, and the back section will go down the back of the tree. Each section of the original portal polygon will receive the unique ID of its parent.
  11. 11. Portal Building Process (4) If the portal polygon is on the splitting plane of a node (not the starting node): The portal polygon must be sent down the front tree first. It may continue to be clipped. All portal polygons that reach leaves in the front tree must be grouped and sent down the back tree. Many portal polygons will be generated this whole clipping process. Not all will be used.
  12. 12. Which portals to use? A portal polygon must exist in two leaves. (like a doorway). Recall that each portal polygon has a unique ID – this allows finding the leaves it ends in. There is a possibility of having two duplicate portal polygons in different leaves. Keep the larger of the two. If a portal ends up in only one leaf it will be rejected. It doesn’t make sense to have a door that doesn’t lead anywhere.
  13. 13. Portal Building Example A BE D CE2 E1 F PB PA PC PF PE2 PD PE1 solid solid solid solid solid solid AFE1 BCE2D Portals: P1, P2, P6, P7 Portals: P1, P3, P4, P5 Portals: P1 from PB P2 from PA P3 from PC P4 from PD P5 from PE2 P6 from PF P7 from PE1
  14. 14. How are Portals Used? A leaf can see whatever it’s portals can see. So, we need to figure out which leaves a portal can see. Then each leaf's visibility will be whatever each portal, contained in the leaf, can see.
  15. 15. Anti-Penumbra clipping Called that because if we were to open a door into a dark room, we are concerned only with the area that will be lit. Since each portal is contained in two leaves we can determine the neighbors (via the portal) of any given leaf. We will assume a data structure or method is available to determine the cross portal neighbors of each leaf. We will also assume that a binary array (PVS array) is maintained for each leaf that indicates whether that leaf is visible from the current leaf.
  16. 16. Anti-Penumbra Clipping Algorithm For each leaf: Mark the current leaf and all its cross-portal neighbors as visible in the PVS array. For each portal contained in the leaf build a set of clip planes to portals in neighbors. Leaf 3 Leaf 2Leaf 1 Leaf 4 Leaf 5 Leaf 6 1 1 0 0 0 0 PVS Array
  17. 17. Anti-Pen. Clipping Alg. (2) Building Clipping Planes: Planes extend from one side of the portal in the current leaf to the opposite side of the portal in the neighbor. Leaves on the opposite side of neighbor portals are now also visible. 21 Leaf 3 Leaf 2Leaf 1 Leaf 4 Leaf 5 Leaf 6 1 1 1 0 0 0 PVS Array
  18. 18. Valid Clipping planes Clipping planes are valid if they are built from opposite sides of each portal. This means that one portal will be on the front side of the clipping plane and the other on the back side. This makes a frustum like shape from one portal to another. With a valid set of clipping planes check to see if any portals lie within them (these portals are now visible). Leaves which contain visible portals are now also visible. Repeat the process recursively using the newly visible portals until no new portals become visible.
  19. 19. Clipping Thus, Leaf 3 becomes visible through portal 2 and Leaf 5 becomes visible because portal 4 is visible between the clipping planes. Leaves 4 and 6 are not visible – no other portals become visible by recursing with portal 4. 21 3 4 Leaf 3 Leaf 2Leaf 1 Leaf 4 Leaf 5 5 Leaf 6 1 1 1 0 1 0 PVS Array
  20. 20. Drawbacks We are doing some pretty major operations. This process can be slow. Quake3 levels can take up to a couple of hours to compile using this process.
  21. 21. Total PVS Size We now have a large byte array which contains the potential visibility information for each leaf. This can be one big array or one array for each leaf. If there are N leaves then the array for each leaf is size N. The total array size is then N2.
  22. 22. Rendering First find out which leaf the camera is in. Lookup visibility info in Master PVS array or in the PVS array for the leaf containing the camera. Check bytes to see which other leafs are visible. If set to 1 leaf is visible, if 0 leaf is not visible. Render all visible leafs polygons. Since we lose our depth sorting information we’ll need to turn on the zbuffer.
  23. 23. Tree Traversal // Find out which leaf the camera is in void Traverse(vector camerapos) { int Node; while(1) { switch(ClassifyPoint(camerapos, currNode.plane) { case Front: if(currNode.isLeaf) { Render(currNode.front); return; } currNode = currNode.front; break; case Back: if(currNode.back == -1) return; // ooops solid space currNode = currNode.back; break; } } }
  24. 24. Rendering Algorithm void Render(int camleaf) { // assumes PVS is one large array // get PVS index of camera leaf long offset = camleaf * numLeafs; for(int i = 0; i < numLeafs; i++){ if(PVSData[offset+i] == 1) Render(i); // for now just render } }
  25. 25. PVS Size Problem Problem we face with storing an array of bytes for PVS. If our level contains 5000 leafs: PVS will be 5000 * 5000 Bytes or approx 24 MB. That’s for visibility info alone. Not counting polygons, textures, etc…
  26. 26. Solving the PVS Size Problem Since the PVS is storing binary (boolean) information. We can store this info in a bit instead of a byte. This brings our memory requirement down to around 3 MB
  27. 27. Zero Run Length Encoding Given that most leafs cannot see most other leafs there will be a lot of zeros in our PVS table. We can take advantage of this by counting the number of consecutive zeros and storing that number in the next byte. Since a byte can only hold up to 255 that is the most zeros we can skip using one byte. This type of encoding can save a large amount of memory. Can take the PVS table from MB to KB.