Click or drag to resize
DigitalRuneOcclusionBuffer Class
Represents an occlusion buffer that supports frustum culling, distance culling, occlusion culling, and shadow caster culling.
Inheritance Hierarchy
SystemObject
  DigitalRune.Graphics.RenderingOcclusionBuffer

Namespace: DigitalRune.Graphics.Rendering
Assembly: DigitalRune.Graphics (in DigitalRune.Graphics.dll) Version: 1.2.0.0 (1.2.1.14562)
Syntax
public class OcclusionBuffer : IDisposable

The OcclusionBuffer type exposes the following members.

Constructors
  NameDescription
Public methodOcclusionBuffer(IGraphicsService)
Initializes a new instance of the OcclusionBuffer with a default size of 512 x 256 and a triangle buffer size of 21845.
Public methodOcclusionBuffer(IGraphicsService, Int32, Int32, Int32)
Initializes a new instance of the OcclusionBuffer class with the specified buffer size.
Top
Methods
  NameDescription
Public methodDispose
Releases all resources used by an instance of the OcclusionBuffer class.
Protected methodDispose(Boolean)
Releases the unmanaged resources used by an instance of the OcclusionBuffer class and optionally releases the managed resources.
Public methodEquals
Determines whether the specified Object is equal to the current Object.
(Inherited from Object.)
Protected methodFinalize
Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection.
(Inherited from Object.)
Public methodGetHashCode
Serves as a hash function for a particular type.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Public methodStatic memberIsOccluder
Determines whether the specified scene node acts as an occluder during occlusion culling.
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodQuery
Tests the specified scene nodes against the occlusion buffer to check which scene nodes are visible. (Performs frustum culling, distance culling, occlusion culling, and shadow caster culling.)
Public methodRender(IListSceneNode, RenderContext)
Clears the occlusion buffer and renders the specified list of occluders.
Public methodRender(IListSceneNode, SceneNodeRenderer, RenderContext)
Clears the occlusion buffer and renders the specified list of occluders.
Public methodRender(IListSceneNode, LightNode, RenderContext)
Clears the occlusion buffer and renders the specified list of occluders.
Public methodRender(IListSceneNode, LightNode, SceneNodeRenderer, RenderContext)
Clears the occlusion buffer and renders the specified list of occluders.
Public methodResetShadowCasters
Resets state of the shadow casters.
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Public methodVisualizeCameraBuffer
Debugging: Visualizes a level of the camera's hierarchical Z buffer.
Public methodVisualizeLightBuffer
Debugging: Visualizes a level of the light's hierarchical Z buffer. (Only valid when shadow caster culling is used.)
Public methodVisualizeObject
Debugging: Visualizes the occlusion query for the specified scene node.
Public methodVisualizeShadowCaster
Debugging: Visualizes the occlusion query for the specified shadow caster.
Public methodVisualizeShadowVolume
Debugging: Visualizes the occlusion query for the specified shadow volume.
Top
Properties
  NameDescription
Public propertyEnableMultithreading
Gets or sets a value indicating whether multithreading is enabled.
Public propertyIsDisposed
Gets a value indicating whether this instance has been disposed of.
Public propertyProgressiveShadowCasterCulling
Gets or sets a value indicating whether progressive shadow caster culling is enabled.
Public propertyStatistics
Gets the occlusion culling statistics.
Top
Remarks

The occlusion buffer can be used to determine which objects in a scene need to be rendered. Objects that are outside the viewing frustum or occluded by other objects don't have to be processed during rendering. The occlusion buffer implements frustum culling, distance culling, occlusion culling, and shadow caster culling.

To use occlusion culling: The method Render(IListSceneNode, RenderContext) clears the occlusion buffer and renders all occluders. This method needs to be called once per frame, even if there are no occluders in the scene. Query(IListSceneNode, RenderContext) performs culling on a list of scene nodes. Scene nodes that are culled are replaced by null entries in the list.

Frustum Culling:
The occlusion buffer implements frustum culling to determine which objects are within the viewing frustum of the camera. Objects outside the viewing frustum are hidden from the camera and do not have to be rendered. (The occlusion buffer can be used for frustum culling instead of using scene queries.)

The following example shows how to use the occlusion buffer for frustum culling. The active camera needs to be set in the render context.

Example: Frustum culling using the occlusion buffer
// Clear the occlusion buffer.
occlusionBuffer.Render(null, context);

// Perform frustum culling on the list of scene nodes. 
// (Scene nodes that culled are replaced by null entries.)
occlusionBuffer.Query(sceneNodes, context);

Distance Culling and LOD Distance:
(Prerequisite: LodCameraNode needs to be set in the render context!)

The occlusion buffer automatically calculates the LOD distance of each scene node in Query(IListSceneNode, RenderContext) and performs distance culling if a MaxDistance is set. Scene nodes that are beyond their max draw distance are removed. The LOD distance of the remaining scene nodes is stored in SortTag. This value can be used for LOD selection (see LodGroupNode and ISceneQuery).

Occlusion Culling:
Occlusion culling is the process of determining which objects are hidden from a certain viewpoint. This is achieved by testing the scene nodes against a set of occluders. An occluder is an object within a scene that obscures the view and prevents objects behind it from being seen.

By calling Render(IListSceneNode, RenderContext) all occluders within a scene are rendered into a depth buffer. The following objects act as occluders during occlusion culling:

Query(IListSceneNode, RenderContext) can be called to test whether scene nodes are visible. (The bounds of the scene nodes are compared with the current occlusion buffer.)

The following example shows how to use the occlusion buffer for occlusion culling.

Example: Occlusion culling using the occlusion buffer
// Render the occluders into the occlusion buffer.
occlusionBuffer.Render(occluders, null, null, context);

// Perform occlusion culling on the list of scene nodes.
// (Scene nodes that are culled are replaced by null entries.)
occlusionBuffer.Query(sceneNodes, context);

The next example shows how to render custom scene nodes into the occlusion buffer. For example, MeshNodes that support an "Occluder" render pass can be rendered directly into the occlusion buffer if the appropriate render is provided.

Example: Rendering custom occluders
// Render the occluders into the occlusion buffer. MeshNodes that do not have an
// occluder but have an "Occluder" render pass are rendered using the MeshRenderer.
context.RenderPass = "Occluder";
occlusionBuffer.Render(occluders, null, meshRenderer, context);
context.RenderPass = null;

// Perform occlusion culling on the list of scene nodes.
// Scene nodes that are culled are replaced by null entries.
occlusionBuffer.Query(sceneNodes, context);

Shadow Caster Culling:
Shadow caster culling determines which shadows contribute to the final image. If the shadow cast by an object is not visible, the object can be culled and does not need to be rendered into the shadow map.

The occlusion buffer implements shadow caster culling for the main directional light of a scene. Multiple directional lights with shadows are not supported.

Shadow caster culling involves the following tests:

  1. Frustum culling in light space: The shadow caster is tested against the light frustum.
  2. Occlusion culling in light space: The shadow caster is tested against the occluders from the light's point of view.
  3. Then the extent of the shadow volume is determined. The actual extent of the shadow volume is unknown. When "progressive" shadow caster culling is enabled (see property ProgressiveShadowCasterCulling), the occlusion buffer estimates the extent of the shadow volume. When "conservative" shadow caster culling is enabled, the occlusion buffer assumes that shadow volume simply extends to the edge of the light space.
  4. Frustum culling camera space: The shadow volume is tested against the camera frustum.
  5. Occlusion culling camera space: The shadow volume is tested against the occluders from the camera's point of view.

"Progressive" shadow caster culling is more aggressive than "conservative" shadow caster culling, but may cause problems: In some cases it is not possible to estimate the correct extent of the shadow volume. A shadow caster might be culled, even though its shadow should be visible. Shadows can start to flicker. In these cases "progressive" shadow caster culling needs to be disabled. The property ProgressiveShadowCasterCulling determines whether progressive shadow caster culling is active.

To perform shadow caster culling the main directional light needs to be passed to the Render(IListSceneNode, LightNode, RenderContext) method.

Example: Occlusion culling and shadow caster culling
// Render the occluders into the occlusion buffer.
// lightNode is the main directional light that casts shadows.
occlusionBuffer.Render(occluders, lightNode, context);

// Perform occlusion culling and shadow caster culling on the
// list of scene nodes.
occlusionBuffer.Query(sceneNodes, context);

Shadow caster that are culled are internally marked using a flag. The ShadowMapRenderer will automatically skip these scene nodes.

Performance:
The methods Render(IListSceneNode, RenderContext) and Query(IListSceneNode, RenderContext) can be called multiple times per frame. However, each call has a certain latency. It is therefore recommended to batch all occluders and scene nodes and call the methods only once per frame.

Occlusion culling is preformed on the GPU. The occlusion culling results needs to be read back from the GPU to the CPU, which may stall the pipeline. Depending on various factors (platform, timing, GPU load, etc.), the process may take less than a millisecond or up to several milliseconds. Occlusion culling should only be used when there is an overall performance gain. This can only be determined by experimentation.

Render Target and Viewport:
Occlusion culling is performed on the GPU. The methods Render(IListSceneNode, RenderContext) and Query(IListSceneNode, RenderContext) override the current render target of the graphics device. The render target and the viewport of the graphics device are undefined after these methods were executed.

The Visualize methods render into the current render target and viewport of the graphics device.

See Also