Frustum & View Frustum Culling - Sixth 3D

Table of Contents

Back to main documentation

1. Frustum & View Frustum Culling

+Z (view direction) Camera Near Far visible region Top plane Bottom plane rendered culled culled

The view frustum is a truncated pyramid-shaped volume that represents everything the camera can see. Objects completely outside this volume are skipped during rendering — a powerful optimization called frustum culling.

1.1. The Six Frustum Planes

The frustum is defined by six clipping planes:

Plane Purpose
Left Left edge of viewport
Right Right edge of viewport
Top Top edge of viewport (smaller Y in Y-down)
Bottom Bottom edge of viewport (larger Y)
Near Closest visible distance from camera
Far Farthest visible distance from camera

Each plane divides 3D space into "inside" (visible) and "outside" (culled). An object must pass all six plane tests to be considered potentially visible.

1.2. Frustum Culling vs Backface Culling

These are complementary optimizations at different levels:

Optimization Level What it skips
Frustum culling Object level Entire composite shapes + children
Backface culling Polygon level Individual triangles facing away

Frustum culling happens first during the transform phase — entire object trees are skipped with a single bounding box test. Backface culling happens later during rasterization — individual triangles are checked before being drawn.

For best performance, use both: organize your scene with composite shapes for effective frustum culling, and enable backface culling on closed meshes.

2. How Frustum Culling Works in Sixth 3D

Frustum culling is applied automatically to all composite shapes during Phase 2 of the rendering loop:

  1. Update frustum: Compute 6 planes from camera FOV and viewport size
  2. For each composite shape:

2.1. The AABB Intersection Algorithm

The intersection test uses an optimized "P-vertex" approach:

P-vertex: corner most aligned with plane normal If P is behind the plane → entire AABB is outside Plane inside frustum outside frustum N inside P outside P

For each plane, instead of testing all 8 corners of the bounding box, we test only the P-vertex — the corner most aligned with the plane normal. If this "best" corner is behind the plane, the entire box must be outside the frustum.

  • Plane normal points into the frustum (toward visible region)
  • P-vertex: select corner based on normal direction
    • If normal.x > 0 → use maxX (rightmost corner)
    • If normal.x < 0 → use minX (leftmost corner)
    • Same logic for Y and Z
  • Test: dot(normal, P-vertex) < distance → outside

This reduces from 48 tests (8 corners × 6 planes) to just 6 tests per object.

3. Performance Benefits

Frustum culling can dramatically improve performance for large scenes:

  • High cull % (60-90%): Excellent — most objects skipped entirely
  • Medium cull % (20-60%): Moderate benefit
  • Low cull % (0-20%): Limited benefit — most objects visible

A composite shape that is culled skips:

  • Transforming all its children
  • Computing bounding boxes for children
  • All polygon-level operations (backface culling, rasterization)

Open Developer Tools (F12) to see real-time frustum culling statistics.

4. Scene Design for Effective Culling

Frustum culling works best when you organize your scene into well-defined composite shapes:

// Good: Each building is a separate composite
AbstractCompositeShape cityBlock = new AbstractCompositeShape();
for (Building building : buildings) {
    AbstractCompositeShape buildingComposite = new AbstractCompositeShape();
    buildingComposite.add(buildingWalls);
    buildingComposite.add(buildingRoof);
    buildingComposite.add(buildingInterior);
    cityBlock.add(buildingComposite);
}

// Less effective: Everything in one giant composite
AbstractCompositeShape allObjects = new AbstractCompositeShape();
allObjects.add(building1Walls);
allObjects.add(building1Roof);
allObjects.add(building2Walls);
// ... hundreds of shapes directly in root

Best practices:

  • Use composites to group objects that occupy a bounded region of space
  • Keep bounding boxes tight (don't add distant objects to the same composite)
  • Nest composites hierarchically for multi-level culling (city → block → building)
  • Call updateBoundingBox() after moving shapes

5. Technical Details

The Frustum class:

  • Computes planes in view space (camera at origin, looking along +Z)
  • FOV derived from projectionScale = width / 3 (≈112° horizontal FOV)
  • Default clip distances: Near = 1.0, Far = 10000.0
  • Planes stored in Hesse normal form: (normal vector, distance)

The frustum is updated once per frame in ShapeCollection.transformAllShapes() before processing composite shapes.

Created: 2026-04-04 Sat 15:41

Validate