Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

A potentially visible set (PVS) is the set of scene geometry that might be visible from somewhere inside a region of space, called a cell or view cell. It is usually computed in advance and stored with each cell. During rendering, a program looks up the cell that contains the viewpoint and draws only the objects or polygons in that cell's set, so hidden geometry is discarded before it reaches the graphics pipeline. A PVS is usually conservative: it contains every visible object plus some hidden ones, and the depth buffer removes whatever is left over.[1]

The technique is a form of occlusion culling. It was developed for interactive walkthroughs of virtual buildings in work by John Airey, John Rohlf and Fred Brooks at the University of North Carolina at Chapel Hill (1990) and by Seth Teller and Carlo Séquin at the University of California, Berkeley (1991).[2][3] John Carmack then built a precomputed PVS into id Software's Quake engine.[4] In virtual reality the method matters because every frame is rendered twice, once per eye, at a high and steady frame rate. Developers of mobile VR games such as Dead Secret and the Samsung Gear VR and Oculus Go version of République built custom PVS systems to cut draw calls. Research on streaming rendering to untethered head-mounted displays has also returned to PVS computation.[5][6][7]

Reviewed 13 October 2026. Every claim checked against the full texts of Airey et al. 1990 and Airey's dissertation, Teller and Séquin 1991, Funkhouser et al. 1992, Cohen-Or et al. 2003, Wonka et al. 2000, Nirenstein et al. 2002 and Hladky et al. 2019, the Teller 1992 and Bittner 2009 abstracts, Abrash's 1996 column, id Software's tool source and notes, Epic, Unity and Godot documentation, the Unity/Umbra blog, Robot Invader's two posts and Darkwind's two Meta blog posts; paper DOIs confirmed via Crossref and DataCite. About review dates.

Definition

Cohen-Or and colleagues define the PVS through the idea of conservative visibility. A conservative visibility set contains at least every visible object and may also contain some invisible ones: an occluded object may be classified as visible, but a visible object may never be classified as occluded. A PVS built this way holds all the visible objects plus a small number of occluded ones for a whole region of space. The set can be defined for a single viewpoint or for a region of space, and the survey notes that from-region methods usually precompute a PVS.[1]

PVS computation is different from hidden surface removal. A hidden surface algorithm works out exactly which parts of each polygon are seen. Occlusion culling only has to find the objects that cannot be seen, and it can safely overestimate, because the hidden surface step that follows (normally the Z-buffer) discards the extra geometry.[1]

Visibility algorithms are often grouped by how they err:

Class Behavior Example
Conservative Overestimates the visible set; never drops a visible object Teller and Séquin's cell-to-cell visibility, which "provably" contains a superset of the PVS[3]
Sampling (approximate) Estimates visibility from rays or sample views; can miss small visible objects Airey's point-sampling method, which casts rays from a cell and may underestimate the set[2]
Aggressive Starts from a conservative method but gives up conservativeness for a tighter set, accepting a small chance of error Described in the 2003 survey[1]
Exact Finds exactly the polygons visible from the region Nirenstein, Blake and Gain's 2002 from-region algorithm[8]

The survey also separates cell-and-portal methods from methods for general scenes. Cell-and-portal methods begin with an empty PVS and add objects that can be seen through a chain of openings. Occluder-based methods begin by assuming everything is visible and then remove objects found to be hidden.[1]

How it works

A PVS system has an offline preprocessing phase and a runtime phase.

In preprocessing, the space the viewer can occupy is divided into cells. The early systems used binary space partitioning or k-d trees whose splitting planes lie on walls, floors and other large opaque surfaces, so cells correspond roughly to rooms. Openings in a cell's boundary, such as doors and windows, are called portals.[2][3] For each cell the system computes the set of objects or polygons that might be seen from any point inside it and stores that set with the cell. Airey et al. described two families of methods for this step. Point sampling with ray casting is simple but may miss polygons. A method based on shadow volumes, which treats portals like area light sources, may include too many.[3] Airey noted that the exact problem is equivalent to finding the polygons directly lit by an area light source.[2] Teller and Séquin instead linked cells through the portal adjacency graph and tested whether a sightline could pass through ("stab") each sequence of portals, a test they solved as a linear programming problem.[3]

At runtime, the program finds the cell that contains the viewpoint, retrieves its PVS and sends only those objects to the renderer. Teller and Séquin further culled the cell's set against the observer's view cone, which they called eye-to-cell visibility, before hardware hidden surface removal. Their system remained conservative at every step.[3] Because a from-region PVS stays valid for many frames, its cost is spread over all of them. It also tells the program what may become visible next, which allows geometry to be prefetched from disk or over a network.[1]

The stored sets take memory. Airey's display file for a 7,125-polygon model grew by about 20 percent, because each cell stored pointers to shared polygons rather than copies.[2] Quake stored each leaf's set as a bit vector, one bit per leaf, and compressed runs of zero bytes.[4][9]

History

Building walkthroughs

Airey, Rohlf and Brooks presented their method at the 1990 Symposium on Interactive 3D Graphics. It was part of the UNC Building Walkthrough project, whose goal was a virtual building environment that simulates a person's experience of a building before it is built. The authors reported that the illusion of the virtual building began to work at around six frames per second, and they used precomputed visibility, precomputed radiosity lighting and adaptive refinement to keep the update rate above that level.[2] On a 7,125-polygon model of Sitterson Hall, rendering only the PVS of the current cell gave speedups of 30 on average and at least 3.25 in the worst case.[2] Airey's July 1990 dissertation, supervised by Brooks, has "Potentially Visible Set Calculations" in its title. It describes the project's interfaces as including joysticks and a treadmill, and names a head-mounted display or large screen as options for clients.[10]

Teller and Séquin presented a conservative alternative at SIGGRAPH 1991. In their test on an axis-aligned floor plan of about 1,000 faces split into about 700 cells, cell-to-cell visibility left 8.1 percent of the model area as potentially visible, a tenfold reduction. Exact eye-to-cell culling with a 60 degree view cone brought this to 1.8 percent.[3] Teller's 1992 dissertation extended the work to non-occluding detail objects such as furniture and wall trim. On a model with almost three-quarters of a million polygons it reduced frame times from about ten seconds to about a tenth of a second.[11] Thomas Funkhouser, Séquin and Teller combined the PVS with level of detail selection and a memory manager that prefetched cells the observer might soon see. On a furnished model of one floor of the planned computer science building at Berkeley, the system culled an average of 97 percent of the model and cut rendering time by an average factor of 39.[12]

Quake

In a 1996 column written while Quake was still in development, Michael Abrash described how Carmack arrived at a precomputed PVS. Carmack had first tried a beam tree, which slowed the frame rate badly in scenes with long view distances, and had also explored other approaches, including portals. He then decided to store in each leaf of the level's BSP tree a list of all leaves visible from that leaf, and at runtime to draw only those leaves back to front. Abrash wrote that an uncompressed PVS was several megabytes, and that a bit vector with zero-byte compression, together with other changes, brought it to about 20 KB for a good-size level. Because the set covers every point in a leaf, some overdraw remained, typically about 50 percent and up to 150 percent, but worst-case performance was no longer much worse than the best case. The column's reference list cites Teller's dissertation and the 1991 Teller and Séquin paper.[4]

The map tools that id Software later released include vis, which generates the PVS for a compiled map after qbsp and light. The notes from id's 1996 developer CD, published with the tools, state that it works only on a leak-free map, and that the -fast option produces a rough PVS quickly.[13] The Quake II tool qvis3 computes visibility between clusters, groups of leaves that share one visibility entry, rather than single leaves.[14][15]

General scenes and exact solutions

Effective from-region methods existed for indoor scenes, but for general scenes such as cities the computation is harder, because objects that hide nothing alone can together hide others (occluder fusion). Methods that perform occluder fusion from a region appeared around 2000, including Durand et al.'s extended projections and Schaufler et al.'s conservative volumetric visibility.[1] Peter Wonka, Michael Wimmer and Dieter Schmalstieg shrank occluders and sampled visibility from points on a view cell's boundary to get a conservative result. They demonstrated it in a walkthrough of an 8 million polygon model of Vienna, where occluder fusion from about 200 visible occluders pruned more than 99 percent of the scene in the view shown.[16]

Exact from-region visibility for general 3D scenes had long been considered intractable. In 2002 Nirenstein, Blake and Gain described an exact algorithm that represents polygons and the lines connecting them in a 5D space derived from Plücker coordinates and subtracts occluded lines. They reported that it could preprocess scenes of millions of polygons.[8] Sampling methods also continued to improve. Bittner et al.'s adaptive global visibility sampling (2009) computes visibility for all view cells at once by sharing each ray among the cells it crosses, and reported more than an order of magnitude speedup over sampling each cell separately.[17]

Use in game engines

Engine or tool Precomputed visibility feature Notes
Quake (id Software) vis map tool Stores a compressed bit vector of visible leaves for each BSP leaf; needs a sealed map[4][13]
Quake II (id Software) qvis3 map tool Works on clusters of leaves[15]
Unreal Engine Precomputed Visibility Volumes Visibility cells are generated during a lighting build; each cell stores which actors are visible; movable actors are not handled[18]
Unity Baked occlusion culling Bakes cells and the visibility between adjacent cells; dynamic objects can be occluded but cannot occlude[19]
Godot 3 Rooms and portals Uses the PVS of rooms from the current room to define the "gameplay area"[20]

Epic Games describes precomputed visibility as most useful for small to medium-sized worlds with mostly static lighting, restricted player movement and "somewhat 2D" play areas, typically on mobile hardware where dynamic occlusion culling is limited. Epic notes that it trades rendering thread time, normally spent on hardware occlusion queries, for more runtime memory and longer lighting builds, and advises placing volumes only where the player or camera can go. Only static shadow-casting triangles act as occluders.[18]

Unity's baked system was built on middleware from Umbra Software. Chris Pruett called it "a pretty high-end PVS system" while finding its controls hard to tune for Dead Secret.[5] In a 2013 Unity blog post, Jasin Bushnaief of Umbra Software explained that the bake voxelizes the scene, groups voxels into cells and connects the cells with portals. At runtime Umbra rasterizes the portals in software into a depth buffer and tests objects against it, and the queries are always conservative.[21] Unity's manual says the built-in system runs queries on the CPU, helps most when a project is GPU-bound because of overdraw, and is not suitable for geometry generated at runtime.[19]

Godot 3's rooms and portals system uses the PVS for more than rendering. It treats any room that can be seen from any part of the current room as part of the gameplay area, and it notifies objects as they enter or leave it, so a game can stop simulating objects far out of view.[20]

Applications in VR and AR

Mobile VR games

Pruett, of Robot Invader, described the PVS system built for Dead Secret, a VR murder mystery designed for mobile headsets such as the Gear VR. He noted that VR renders each frame twice and that dropping below 60 fps can be felt by the player. A normal render of the game's house, with only standard culling, needed about 1,400 draw calls per eye, while a closed room needed about 60. Casting about 26,000 rays from each vantage point missed small, thin objects and took about seven hours. Pruett switched to rendering color-coded panoramas, in which each mesh gets a unique solid color and the pixels show which meshes are visible. This was about 60 times faster (seven minutes for the whole world instead of seven hours), and the game ran at a solid 60 fps on Gear VR.[5] For the sequel Dead Secret Circle, which lets the player move freely, Robot Invader precomputed visibility for every cell of a 3D grid that the game can index in constant time, with extra renders for doors that open and close. Restricting cells to hand-placed volumes and tuning their size per area cut the bake for one apartment level from about 20 minutes to 1.5 minutes.[22]

In 2019 Darkwind Media described a similar system on Meta's developer blog for its Gear VR and Oculus Go port of Camouflaj's République. The team found Unity's general-purpose occlusion culling could not assume where the camera would be, and it did not want any per-frame CPU cost. Because nearly every in-game camera is fixed, it baked one PVS per camera from a 360 degree capture made of six 512 by 512 color-coded images, with repeated passes so that transparent objects are counted as visible without hiding what lies behind them.[6] For a drone camera that moves along a rail, the team described joining capture points into cells and storing only the differences between neighboring cells' sets. The team noted that games for headsets with six degrees of freedom might need a 2D or 3D grid of cells, and that the head and neck model of the 3DOF headsets still moves the camera slightly, which matters near corners. One area needing 385 cubemaps was processed in under 25 seconds. The listed limitations were static geometry only, a rebake whenever static objects change, the memory and load time of the data, and the fact that culled objects cannot cast real-time shadows.[23]

Streaming rendering for headsets

Hladky, Seidel and Steinberger argued in 2019 that VR, especially the limited graphics of untethered headsets, has made potential visibility important again. They proposed a split pipeline in which a server computes the PVS, shades the potentially visible triangles and sends them to the headset, which renders new views for the user's current head pose. Their camera offset space method computes a complete PVS on the GPU (using OpenGL and CUDA) on the fly, without preprocessing, so it supports dynamic objects. Their tests covered head movements of 5 to 30 cm and rotations of plus or minus 15 to 60 degrees. The authors note that the earlier Shading Atlas Streaming system sampled visibility from a reference view, which can miss small triangles and cause holes and flicker, and that sampling errors in PVS computation can produce significant flickering in VR.[7][24]

Limitations

Because from-region methods usually precompute the PVS, they handle dynamic scenes poorly: if occluders move, the data has to be recomputed, although objects that are only occluded can be handled by bounding their motion. The same survey notes that from-region algorithms usually need long preprocessing and significant storage.[1] Engine documentation and developer reports give the practical form of these costs: more runtime memory, longer builds, and a rebake after every change to static geometry.[18][23]

A region's set includes everything visible from anywhere in the region, so more is drawn than can be seen from any single point; Abrash put the resulting overdraw in Quake at typically about 50 percent and up to 150 percent.[4] Sets built by sampling can miss small objects, which shows up as missing geometry, holes or flicker.[3][5][7]

See also

References

  1. ↑ 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 Daniel Cohen-Or, Yiorgos L. Chrysanthou, Cláudio T. Silva, Frédo Durand (2003). "A Survey of Visibility for Walkthrough Applications". IEEE Transactions on Visualization and Computer Graphics, vol. 9, no. 3, pp. 412-431. IEEE Computer Society. doi:10.1109/TVCG.2003.1207447. https://www.cs.princeton.edu/courses/archive/fall16/cos526/papers/cohenor03.pdf. Retrieved 2026-10-13.
  2. ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 John M. Airey, John H. Rohlf, Frederick P. Brooks Jr. (1990). "Towards Image Realism with Interactive Update Rates in Complex Virtual Building Environments". Proceedings of the 1990 Symposium on Interactive 3D Graphics (Computer Graphics, vol. 24, no. 2), pp. 41-50. ACM. doi:10.1145/91385.91416. https://techreports.cs.unc.edu/papers/90-001.pdf. Retrieved 2026-10-13.
  3. ↑ 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Seth J. Teller, Carlo H. Séquin (1991-07). "Visibility Preprocessing for Interactive Walkthroughs". Computer Graphics (Proceedings of SIGGRAPH '91), vol. 25, no. 4, pp. 61-70. ACM. doi:10.1145/122718.122725. https://www.cs.princeton.edu/courses/archive/spr01/cs598b/papers/teller91.pdf. Retrieved 2026-10-13.
  4. ↑ 4.0 4.1 4.2 4.3 4.4 Michael Abrash (1996). "Inside Quake: Visible-Surface Determination". Dr. Dobb's (Ramblings in Real Time column). https://jacobfilipp.com/DrDobbs/articles/DDJ/1996/9613/9613f/9613f.htm. Retrieved 2026-10-13.
  5. ↑ 5.0 5.1 5.2 5.3 Chris Pruett (2014-12-22). "Custom Occlusion Culling in Unity". Robot Invader blog. Robot Invader. http://robotinvader.com/blog/?p=460. Retrieved 2026-10-13.
  6. ↑ 6.0 6.1 Darkwind Team (2019-05-27). "Occlusion Culling for Mobile VR - Part 1: Developing a Custom Solution". Meta for Developers blog. Meta. https://developers.meta.com/horizon/blog/occlusion-culling-for-mobile-vr-developing-a-custom-solution/. Retrieved 2026-10-13.
  7. ↑ 7.0 7.1 7.2 Jozef Hladky, Hans-Peter Seidel, Markus Steinberger (2019-11). "The Camera Offset Space: Real-time Potentially Visible Set Computations for Streaming Rendering". ACM Transactions on Graphics, vol. 38, no. 6, article 231. ACM. doi:10.1145/3355089.3356530. https://www.tugraz.at/fileadmin/user_upload/Institute/ICG/Downloads/team_steinberger/Publications/CameraOffsetSpace.pdf. Retrieved 2026-10-13.
  8. ↑ 8.0 8.1 S. Nirenstein, E. Blake, J. Gain (2002). "Exact From-Region Visibility Culling". Thirteenth Eurographics Workshop on Rendering, pp. 191-202. Eurographics Association. doi:10.2312/EGWR/EGWR02/191-202. https://people.cs.uct.ac.za/~edwin/MyBib/2002-egwr.pdf. Retrieved 2026-10-13.
  9. ↑ "Quake-Tools: qutils/VIS/VIS.C". GitHub. id Software. https://github.com/id-Software/Quake-Tools/blob/master/qutils/VIS/VIS.C. Retrieved 2026-10-13.
  10. ↑ John Milligan Airey (1990-07). "Increasing Update Rates in the Building Walkthrough System with Automatic Model-Space Subdivision and Potentially Visible Set Calculations". Ph.D. dissertation, TR90-027, Department of Computer Science, University of North Carolina at Chapel Hill. https://techreports.cs.unc.edu/papers/90-027.pdf. Retrieved 2026-10-13.
  11. ↑ Seth Jared Teller (1992-10). "Visibility Computations in Densely Occluded Polyhedral Environments". Technical Report UCB/CSD-92-708, EECS Department, University of California, Berkeley. https://www2.eecs.berkeley.edu/Pubs/TechRpts/1992/6250.html. Retrieved 2026-10-13.
  12. ↑ Thomas A. Funkhouser, Carlo H. Séquin, Seth J. Teller (1992). "Management of Large Amounts of Data in Interactive Building Walkthroughs". Proceedings of the 1992 Symposium on Interactive 3D Graphics, pp. 11-20. ACM. doi:10.1145/147156.147158. https://www.cs.princeton.edu/~funk/symp92.pdf. Retrieved 2026-10-13.
  13. ↑ 13.0 13.1 "Quake-Tools: qutils/README.TXT (Quake Development CD notes, 9/4/96)". GitHub. id Software. https://github.com/id-Software/Quake-Tools/blob/master/qutils/README.TXT. Retrieved 2026-10-13.
  14. ↑ "Quake-2-Tools: bsp/qbsp3/prtfile.c". GitHub. id Software. https://github.com/id-Software/Quake-2-Tools/blob/master/bsp/qbsp3/prtfile.c. Retrieved 2026-10-13.
  15. ↑ 15.0 15.1 "Quake-2-Tools: bsp/qvis3/qvis3.c". GitHub. id Software. https://github.com/id-Software/Quake-2-Tools/blob/master/bsp/qvis3/qvis3.c. Retrieved 2026-10-13.
  16. ↑ Peter Wonka, Michael Wimmer, Dieter Schmalstieg (2000). "Visibility Preprocessing with Occluder Fusion for Urban Walkthroughs". Rendering Techniques 2000 (Eurographics Workshop on Rendering), pp. 71-82. Springer. doi:10.1007/978-3-7091-6303-0_7. https://www.cg.tuwien.ac.at/research/vr/occfusion/wonka_EGWR2000.pdf. Retrieved 2026-10-13.
  17. ↑ Jiří Bittner, Oliver Mattausch, Peter Wonka, Vlastimil Havran, Michael Wimmer (2009). "Adaptive Global Visibility Sampling". ACM Transactions on Graphics, vol. 28, no. 3, article 94. ACM. doi:10.1145/1531326.1531400. https://www.cg.tuwien.ac.at/research/publications/2009/BITTNER-2009-AGVS/. Retrieved 2026-10-13.
  18. ↑ 18.0 18.1 18.2 "Precomputed Visibility Volumes in Unreal Engine". Unreal Engine 5.8 Documentation. Epic Games. https://dev.epicgames.com/documentation/en-us/unreal-engine/precomputed-visibility-volumes-in-unreal-engine. Retrieved 2026-10-13.
  19. ↑ 19.0 19.1 "Occlusion culling". Unity Manual (Unity 6.6). Unity Technologies. https://docs.unity3d.com/Manual/OcclusionCulling.html. Retrieved 2026-10-13.
  20. ↑ 20.0 20.1 "Advanced Room and Portal usage". Godot Engine 3.6 documentation. https://docs.godotengine.org/en/3.6/tutorials/3d/portals/advanced_room_and_portal_usage.html. Retrieved 2026-10-13.
  21. ↑ Jasin Bushnaief (2013-12-02). "Occlusion culling in Unity 4.3: The basics". Unity Blog. Unity Technologies. https://unity.com/blog/engine-platform/occlusion-culling-basics-unity-4-3. Retrieved 2026-10-13.
  22. ↑ Chris Pruett (2017-07-30). "Dev Diary: Custom Occlusion Culling in Unity Improved". Robot Invader blog. Robot Invader. http://robotinvader.com/blog/?p=554. Retrieved 2026-10-13.
  23. ↑ 23.0 23.1 Darkwind Team (2019-06-04). "Occlusion Culling for Mobile VR - Part 2: Moving Cameras and Other Insights". Meta for Developers blog. Meta. https://developers.meta.com/horizon/blog/occlusion-culling-for-mobile-vr-part-2-moving-cameras-and-other-insights/. Retrieved 2026-10-13.
  24. ↑ Joerg H. Mueller, Philip Voglreiter, Mark Dokter, Thomas Neff, Mina Makar, Markus Steinberger, Dieter Schmalstieg (2018). "Shading Atlas Streaming". ACM Transactions on Graphics, vol. 37, no. 6. ACM. doi:10.1145/3272127.3275087. https://doi.org/10.1145/3272127.3275087. Retrieved 2026-10-13.