XNA 4 tutorial: Frustum Culling and Occlusion Culling

Quelle: http://www.andrejeworutzki.de/game-developement/xna-4-tutorial-frustum-and-occlusion-culling/

This is a short tutorial about improving performance by implementing Frustum Culling and Occlusion Culling.

frustum-culling

Frustum Culling

Frustum Culling determines, if a 3D model is within a View Frustum – if it is visible or not. Video cards do Frustum Culling on triangle-vertex base: vertices outside the View Frustum are not processed. Within a game engine further optimization can be done by reducing the number of objects even sent to the video card. XNA already comes with classes for this kind of collision detection, so applying Frustum Culling is pretty easy in XNA:

// -> within QuaternionCamera class
bool InView(BoundingSphere boundingSphere)
{
    return new BoundingFrustum(View * Projection).Intersects(boundingSphere);
}

// -> within ModelEntityComponent class
public override void Update(GameTime gameTime)
{
    InViewFrustum = Camera.InViewFrustum(BoundingShape.Transform(World));

    base.Update(gameTime);
}

public override void Draw(GameTime gameTime)
{
    if (InViewFrustum)
    {
        // Needed because a loaded Model is shared between several entities.
        EntityHelper.AssignEffectToModelMesh(Model, Effect);

        Model.Draw(World, Camera.View, Camera.Projection);
    }

    base.Draw(gameTime);
}

Note: This implementation requires the Triangle Content Processor, which generates a Bounding Sphere once before starting the application. Calculating the Bounding Sphere at runtime would result in unnecessary performance losses.

Occlusion Culling

occlusion-culling Occlusion Culling is a related, but far more advanced, performance technique. The idea is filtering objects hidden by other objects and don’t sent them to the video card at all. XNA provides the OcclusionQuery class for this purpose. It determines how many pixels of an object were actually been drawn during the last scene. A low-polygon-version of an object or its bounding shape is used to accelerate the occlusion query. Please note that any performance boost of Occlusion Culling strongly depends on the application, since additional computation is required in the first place.
Shawn Hargreaves stated on the AppHub forum following about Occlusion Culling:
„Using GPU hardware queries to cull occluded objects is a pretty advanced scenario. If you aren’t extremely careful, you can easily end up with pipeline stalls costing way more time than the culling saves you.
For the vast majority of games (and for anyone who doesn’t have a pretty deep understanding of how the GPU hardware pipeline works), I would recommend doing CPU culling using some kind of hierarchical spatial partitioning (such as an octree or kdtree) against the camera frustum.
GPU occlusion queries are a pretty esoteric feature, but as well as culling scene geometry, they can be useful for some GP-GPU scenarios, and are very handy for special effects like lensflares (they’re the typical way to handle things like „is the sun hidden behind a tree?“).“

A common scenario of Occlusion Culling are Lens Flares, please have a look at the example on AppHub.