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

View frustum culling (also called viewing frustum culling, frustum culling or VFC) is a rendering optimization in real-time computer graphics that skips objects lying entirely outside the volume a virtual camera can see. That volume, the view frustum, is a pyramid with its apex at the eye and its top cut off by a near plane, bounded by six planes in total. Each object, or each node of a scene hierarchy, is given a simple bounding volume that is tested against these planes; anything found completely outside is never sent to the graphics pipeline.[1] In the 2003 survey of visibility algorithms by Daniel Cohen-Or, Yiorgos Chrysanthou, Cláudio Silva and Frédo Durand, view frustum culling and back-face culling are the two classical strategies with which visibility culling starts; occlusion culling is treated as a separate and more complex problem.[2]

The technique is a default part of current game engines. Unity's manual states that cameras perform frustum culling by default,[3] and Unreal Engine applies view frustum culling as the second of its four culling stages, after distance culling.[4] In virtual reality (VR) and augmented reality (AR), a head-mounted display needs one view per eye, so an engine either culls against each eye's frustum separately or culls once against a single combined frustum that encloses both eyes. Unity, Oculus and Autodesk have all described the combined approach as a way to cut the cost of stereoscopic rendering.[5][6][7]

Reviewed 13 October 2026. Every claim checked against the cited papers (Assarsson, Cohen-Or, Gribb-Hartmann, Clark, Haar-Aaltonen, Johansson; DOIs via Crossref) and the Unity, Unreal, OpenXR, Vulkan, Autodesk, NVIDIA and Oculus/Arm documents. About review dates.

Definition

Ulf Assarsson describes the view frustum as the pyramid-shaped volume in front of the viewer within the field of view, with the eye at the top. Four planes form the sides of the pyramid and pass through the borders of the window; a near plane and a far plane are usually added, which cut off the top of the pyramid and limit its depth, so that the frustum is defined by six planes. Objects outside it are not visible (reflections being a possible exception) and do not need to be rendered.[1] Unity's documentation gives the same picture for a perspective camera: the viewing volume is a pyramid with its apex at the camera, and objects beyond the far clipping plane are excluded from rendering.[8]

Rather than testing an object's own geometry, the culler gives each object a bounding volume that is faster to test and that encloses the object completely while fitting it as tightly as possible; bounding spheres and bounding boxes are the usual choices. A test against the six planes has three outcomes. If the bounding volume is inside all six planes, the object is entirely inside the frustum and is rendered. If it is outside at least one plane, the object is entirely outside and is skipped. Otherwise the object is sent for rendering, because it may be visible.[1] The method is therefore conservative: it may draw some objects that turn out to be off screen, but it does not discard anything that could be seen. Cohen-Or and colleagues define this property, conservative visibility, as allowing an occluded or invisible object to be classified as visible but never the reverse.[2]

Culling is separate from clipping, which the GPU performs on individual primitives. In the Vulkan specification, primitives are culled against a cull volume and then clipped to a clip volume after vertex processing, and the view volume is defined in clip coordinates.[9] View frustum culling works earlier, at the level of whole objects or groups of objects, before any draw call is issued. Unreal Engine's documentation describes it as using the visible screen area of the camera's field of view to cull objects that are not within that space, removing all other objects to save processing time.[4]

How it works

Extracting the frustum planes

An engine needs the six plane equations of the frustum in the same coordinate space as its bounding volumes. In a short paper dated 15 June 2001, Gil Gribb and Klaus Hartmann presented a method that extracts the six planes directly from the combined world, view and projection matrix, in camera space, world space or object space: the projection matrix alone gives the planes in camera space, the view and projection matrices together give them in world space, and adding the world matrix gives them in object space. After the projection transform, the frustum becomes an axis-aligned box in homogeneous clip space, and each inequality that defines the box (for example, that the transformed x coordinate is greater than minus w) gives one plane. In the Direct3D convention, for instance, the left clipping plane is the sum of the fourth and first columns of the matrix. The paper gives versions for both Direct3D and OpenGL and notes that the resulting plane equations are not normalized.[10]

Testing a bounding box against a plane

A naive test of a box against a plane checks all eight corners. Only two corners are needed: the ones on the box diagonal most closely aligned with the plane's normal, known as the n-vertex and the p-vertex. If the n-vertex is outside the plane, the whole box is outside and the test stops; if the p-vertex is inside, the whole box is inside that plane; otherwise the box intersects it. Assarsson and Tomas Möller credit the two-vertex test to earlier work by Eric Haines and John Wallace, Ned Greene, and Daniel Green and Don Hatch. For axis-aligned boxes, the indices of the n- and p-vertices depend only on the signs of the plane normal, so they can be computed once per plane per frame and looked up in a table, which avoids conditional branches.[1]

Hierarchical culling

View frustum culling is often performed hierarchically, to avoid testing every object in turn. Nearby objects are grouped and given a bounding volume that encloses all of their members, those groups are grouped again, and so on until one bounding volume encloses the whole scene. At render time the tree is traversed from the root. A node whose bounding volume is entirely inside the frustum has its whole subtree marked for rendering, a node that is entirely outside is pruned with everything below it, and a node that intersects the frustum is tested further.[1] A related saving, called masking, comes from the observation that if a node's bounding volume lies completely inside one frustum plane, all of its children do too, so that plane need not be tested again in the subtree.[1]

Spatial data structures can serve as the hierarchy. Assarsson and Möller note that view frustum culling can be based on binary space partitioning (BSP) trees, with the drawback that BSP trees only represent static environments.[1]

Exploiting coherence

Because the camera moves only a little between frames, results from the previous frame are good predictors. In their paper "Optimized View Frustum Culling Algorithms for Bounding Boxes", published in the Journal of Graphics Tools in 2000, Assarsson and Möller introduced three optimizations for hierarchies of axis-aligned and oriented bounding boxes:[11][1]

Optimization Idea Limitation stated by the authors
Plane-coherency test If a bounding volume was outside one frustum plane in the previous frame, that plane's index is cached and tested first, in the hope of a fast rejection. None stated; the authors recommend it for both symmetric and asymmetric frustums.
Octant test The frustum is split in half along each axis into eight octants. For a symmetric frustum, it is enough to test a bounding sphere against the three outer planes of the octant that contains its center, which can halve the number of plane tests. Cannot be used for asymmetric frustums. The authors name the CAVE as an exception to the usual symmetric case.
Translation and rotation (TR) coherency test For objects that have not moved, a frustum that has only rotated about one of its axes lets a box that was outside a plane be rejected again at once, and a frustum that has only translated shifts every distance to a plane by the same precomputed amount. Applies only when the view change is limited in this way, and only to objects that have not moved.

The authors reported culling 2 to 11 times faster than other view frustum culling algorithms for axis-aligned and oriented bounding boxes, depending on the circumstances. Their measurements used three factory models with between 52,000 and 184,000 polygons on a dual Pentium II 200 MHz machine, and the speedups were measured for the culling step alone against a culler that tested boxes in the perspective coordinate system. Masking was not found to be competitive with the other methods. The authors recommended the plane-coherency and octant tests for symmetric frustums and the plane-coherency and TR tests for asymmetric ones.[1]

A different approach came from the VR research community. At the ACM Symposium on Virtual Reality Software and Technology (VRST) in 1997, Mel Slater and Yiorgos Chrysanthou of University College London presented "View volume culling using a probabilistic caching scheme".[12] Assarsson and Möller summarize it as a view frustum culler based on a probabilistic caching scheme using ellipsoids, with speedups comparable to their own, but one that may erroneously cull objects that should be visible.[1]

GPU-driven culling

In a GPU-driven rendering pipeline, the GPU itself determines which objects are rendered. In their SIGGRAPH 2015 Advances in Real-Time Rendering talk, Ulrich Haar of Ubisoft Montreal and Sebastian Aaltonen of RedLynx described such a pipeline. Their motivation for Assassin's Creed Unity was that the game had about ten times as many instances as previous games in the series, while the CPU was the scarcest resource on consoles. The pipeline they presented does coarse frustum culling on the CPU with a quadtree, then lets the GPU cull instances (frustum and occlusion) and mesh clusters (frustum, occlusion and triangle back-face) before drawing them through indirect draw calls, so that no round trip between the CPU and GPU is needed. In Assassin's Creed Unity, meshes were drawn in clusters of 64 triangles, each culled on the GPU by its own bounds.[13]

Mesh shading hardware takes the same idea further. Introducing the mesh shader pipeline of NVIDIA's Turing GPUs in 2018, Christoph Kubisch listed vertex and attribute fetch for data that is not visible (because of back-face, frustum or sub-pixel culling) among the wasteful work done by the fixed-function pipeline, and described the new task shader as a stage that can cull a group of primitives early.[14]

History

Cohen-Or and colleagues name James H. Clark among the pioneers of visibility work for large scenes.[2] Clark's 1976 paper "Hierarchical geometric models for visible surface algorithms" in Communications of the ACM proposed organizing a scene as a geometric hierarchy. One of the improvements he listed was that "clipping" becomes "a very fast logarithmic search for the resolvable parts of the environment within the field of view", and that frame-to-frame coherence and clipping define a graphical "working set" of the scene to keep in primary memory.[15] Clark also listed a way to vary the amount of detail presented in a scene, an idea now known as level of detail.[15] Assarsson and Möller cite Clark's paper for the common practice of running a view frustum culling algorithm on a bounding volume hierarchy.[1]

The 2003 survey credits a 1990 SIGGRAPH course chapter by B. Garlick, D. Baum and J. Winget with describing top-down view frustum culling on a scene hierarchy; according to the survey, almost all of the occlusion culling algorithms it reviews perform their tests top-down on such a hierarchy in the same way.[2] Plane-box tests were refined in the Graphics Gems series in the mid-1990s, Assarsson and Möller's coherence tests followed in 2000, and Gribb and Hartmann's plane extraction method appeared in 2001.[1][10]

Relation to other culling methods

Method What it removes Notes
View frustum culling Objects entirely outside the camera's view volume Does not check whether objects are occluded.[3]
Back-face culling Geometry that faces away from the viewer One of the two classical strategies with frustum culling.[2]
Occlusion culling Objects inside the frustum but hidden behind other geometry Involves relationships between objects, so it is far more complex.[2]
Distance culling Objects beyond a set distance from the camera Applied before frustum culling in Unreal Engine.[4]

Unity's manual points out that frustum culling does not check whether a renderer is occluded by other objects, so an object hidden behind a wall is still drawn unless occlusion culling is also enabled; with occlusion culling on, cameras perform both.[3] Unreal Engine orders its methods by cost: distance, view frustum, precomputed visibility and then dynamic occlusion.[4] A potentially visible set (PVS), defined for a single viewpoint or a region of space, includes all visible objects plus a, ideally small, number of occluded ones.[2]

Applications in VR and AR

Two views per frame

A stereo headset renders the scene from two viewpoints. In the OpenXR standard, each view returned to the application has its own pose and its own field of view, given as four separate angles (left, right, up and down). The specification describes the symmetric field of view, in which the left and right angles and the up and down angles mirror each other, as one particular case, so an eye's frustum can be asymmetric.[16][17] This matters for some classic culling optimizations: Assarsson and Möller's octant test assumes a symmetric frustum and cannot be used with an asymmetric one.[1]

Mikael Johansson's 2016 study of rendering building information models on HMDs such as the Oculus Rift noted that stereo rendering had traditionally been implemented as two independent, serial passes, effectively doubling the geometry workload on both the CPU and the GPU, at a time when the consumer Oculus Rift and HTC Vive had set a minimum frame rate of 90 Hz (11.1 ms per frame). With only view frustum culling, his test models were primarily CPU-bound because of the large number of draw calls; occlusion culling alone was enough to reach the required frame rates on the interior camera paths.[18]

Combined frustum for both eyes

Because the two eye views are nearly the same, engines can cull once for both. Cass Everitt of Oculus,[19] in his notes for the SIGGRAPH 2016 Moving Mobile Graphics course, explained that an application aware of stereo can build a single command stream for both eyes, each with its own view and projection transform, and still do frustum culling during the traversal by using a "combined eye" frustum that contains both eye frusta; he added that the math is also available in the Oculus SDK source.[6]

Unity described its implementation in 2017. In its initial implementation, frustum culling generated two lists of objects, one per eye. For its multi-pass stereo mode, Unity instead used a unified culling frustum shared between the eyes, citing Everitt's post. Each eye then renders a little more than it would with its own frustum, but Unity judged that the benefit of a single cull outweighs the cost of some extra vertex shading, clipping and rasterization.[5] Unity's scripting reference states that in side-by-side single-pass stereo, scene culling and shadow map rendering are shared between both eyes.[20] The same blog post explains that single-pass stereo rendering was not twice as fast as multi-pass partly because the multi-pass mode was already optimized for culling and shadows.[5]

Autodesk's 3ds Max Interactive engine, which supported the Oculus Rift, HTC Vive and mobile VR devices, used a "compound frustum". Its documentation lists three uses of the camera frustum (frustum culling, cascaded shadow maps and the clustered deferred shading pass), says that doing all three twice for each eye is "costly and unnecessary", and reasons that because both eyes look in the same general direction and the interpupillary distance is small, a single enclosing frustum is worth computing to save work on the render and GPU threads.[7]

Stereoscopic visualization research had used a single cull for both eyes earlier. In a 2008 Optical Engineering paper on real-time stereoscopic visualization of urban models containing 7.8 million and 23 million polygons, Türker Yilmaz and Uğur Güdükbay carried out view frustum culling once for both eyes by applying a transformation to the culling location, alongside occlusion culling and an off-axis stereo projection.[21]

Related VR rendering techniques

Frustum culling is one of several ways VR renderers avoid work that cannot reach the display. Autodesk's documentation pairs the compound frustum with a hidden area mask, a mesh drawn first into the depth stencil buffer to cull pixels that are not visible through the HMD, so that post-processing is applied only to visible pixels; the documentation notes that the mask came from the headset SDK and was available only for the HTC Vive.[7] Occlusion culling and foveated rendering are separate methods that reduce work inside the frustum.

See also

References

  1. ↑ 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 Ulf Assarsson (2001). "View Frustum Culling and Animated Ray Tracing: Improvements and Methodological Considerations (Licentiate thesis, Technical Report no. 396L)". Department of Computer Engineering, Chalmers University of Technology. Chalmers University of Technology. https://www.cse.chalmers.se/~uffe/lic.pdf. Retrieved 2026-10-13.
  2. ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 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.
  3. ↑ 3.0 3.1 3.2 "Occlusion culling". Unity Manual (Unity 6.0). Unity Technologies. https://docs.unity3d.com/6000.0/Documentation/Manual/OcclusionCulling.html. Retrieved 2026-10-13.
  4. ↑ 4.0 4.1 4.2 4.3 "Visibility and Occlusion Culling in Unreal Engine". Unreal Engine 5.8 Documentation. Epic Games. https://dev.epicgames.com/documentation/en-us/unreal-engine/visibility-and-occlusion-culling-in-unreal-engine. Retrieved 2026-10-13.
  5. ↑ 5.0 5.1 5.2 Rob Srinivasiah (2017-11-21). "How to maximize AR and VR performance with advanced stereo rendering". Unity Blog. Unity Technologies. https://web.archive.org/web/20231201103727/https://blog.unity.com/technology/how-to-maximize-ar-and-vr-performance-with-advanced-stereo-rendering. Retrieved 2026-10-13.
  6. ↑ 6.0 6.1 Cass Everitt (2016). "Multiview Rendering (presentation slides with notes)". Moving Mobile Graphics course, SIGGRAPH 2016. Arm Community. https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/5_2D00_mmg_2D00_siggraph2016_2D00_multiview_2D00_cass.pdf. Retrieved 2026-10-13.
  7. ↑ 7.0 7.1 7.2 "VR performance and the interactive engine". 3ds Max Interactive 2018 Help. Autodesk. https://help.autodesk.com/cloudhelp/2018/ENU/Max-Interactive-Help/interactive_help/getting_started/get_started_vr/vr_engine.html. Retrieved 2026-10-13.
  8. ↑ "Introduction to the camera view". Unity Manual (Unity 6.0). Unity Technologies. https://docs.unity3d.com/6/Documentation/Manual/UnderstandingFrustum.html. Retrieved 2026-10-13.
  9. ↑ "Fixed-Function Vertex Post-Processing". Vulkan Specification. The Khronos Group. https://docs.vulkan.org/spec/latest/chapters/vertexpostproc.html. Retrieved 2026-10-13.
  10. ↑ 10.0 10.1 Gil Gribb, Klaus Hartmann (2001-06-15). "Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix". Technical paper (mirror copy). https://www.gamedevs.org/uploads/fast-extraction-viewing-frustum-planes-from-world-view-projection-matrix.pdf. Retrieved 2026-10-13.
  11. ↑ Ulf Assarsson, Tomas Möller (2000). "Optimized View Frustum Culling Algorithms for Bounding Boxes". Journal of Graphics Tools, vol. 5, no. 1, pp. 9-22. doi:10.1080/10867651.2000.10487517. https://doi.org/10.1080/10867651.2000.10487517. Retrieved 2026-10-13.
  12. ↑ Mel Slater, Yiorgos Chrysanthou (1997-09). "View volume culling using a probabilistic caching scheme". Proceedings of the ACM Symposium on Virtual Reality Software and Technology (VRST '97), Lausanne, pp. 71-77. ACM. doi:10.1145/261135.261150. https://doi.org/10.1145/261135.261150. Retrieved 2026-10-13.
  13. ↑ Ulrich Haar, Sebastian Aaltonen (2015). "GPU-Driven Rendering Pipelines". Advances in Real-Time Rendering in Games course, SIGGRAPH 2015. https://advances.realtimerendering.com/s2015/aaltonenhaar_siggraph2015_combined_final_footer_220dpi.pdf. Retrieved 2026-10-13.
  14. ↑ Christoph Kubisch (2018-09-17). "Introduction to Turing Mesh Shaders". NVIDIA Technical Blog. NVIDIA. https://developer.nvidia.com/blog/introduction-turing-mesh-shaders/. Retrieved 2026-10-13.
  15. ↑ 15.0 15.1 James H. Clark (1976-10). "Hierarchical geometric models for visible surface algorithms". Communications of the ACM, vol. 19, no. 10, pp. 547-554. doi:10.1145/360349.360354. https://doi.org/10.1145/360349.360354. Retrieved 2026-10-13.
  16. ↑ "XrView(3) Manual Page". OpenXR 1.1 Specification. The Khronos Group. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrView.html. Retrieved 2026-10-13.
  17. ↑ "XrFovf(3) Manual Page". OpenXR 1.1 Specification. The Khronos Group. https://registry.khronos.org/OpenXR/specs/1.1/man/html/XrFovf.html. Retrieved 2026-10-13.
  18. ↑ Mikael Johansson (2016). "Efficient Stereoscopic Rendering of Building Information Models (BIM)". Journal of Computer Graphics Techniques, vol. 5, no. 3. https://jcgt.org/published/0005/03/01/. Retrieved 2026-10-13.
  19. ↑ "Moving Mobile Graphics". Arm Community Blogs. Arm. https://developer.arm.com/community/arm-community-blogs/b/mobile-graphics-and-gaming-blog/posts/moving-mobile-graphics. Retrieved 2026-10-13.
  20. ↑ "Rendering.SinglePassStereoMode.SideBySide". Unity Scripting API. Unity Technologies. https://docs.unity3d.com/ScriptReference/Rendering.SinglePassStereoMode.SideBySide.html. Retrieved 2026-10-13.
  21. ↑ Türker Yilmaz, Uğur Güdükbay (2008-09). "Stereoscopic urban visualization based on graphics processor unit". Optical Engineering, vol. 47, no. 9, article 097005. SPIE. doi:10.1117/1.2978948. https://doi.org/10.1117/1.2978948. Retrieved 2026-10-13.