Conditional Render

The Extension NV_conditional_render adds a major improvement to occlusion queries: it allows a simple if ( SamplesPassed > 0 ) conditional to decide whether an object should be drawn based on the result of an occlusion query.

This is probably best shown by a simple example, in the given scene there are 3 objects:

  • A huge cylinder which acts as occluder. Think of it as a pillar in the center of the "room".
  • A small cube which acts as ocludee. Think of it as a box that is anywhere in the "room" but not intersecting the pillar.
  • A small sphere which sits ontop of the cube. If the cube is fully occluded by the cylinder, drawing the sphere can be skipped.

Here is some pseudo-code how the implementation looks like.

uint MyOcculsionQuery;
 
public void OnLoad()
{
  GL.GenQueries(1, out MyOcculsionQuery);
  // etc...
  GL.Enable( EnableCap.DepthTest ); 
}
 
public void OnUnload()
{
  GL.DeleteQueries(1, ref MyOcculsionQuery);
  // etc...
}
 
public void OnRenderFrame()
{
  // The cylinder is drawn unconditionally and used as occluder for the Cube and Sphere
  MyCylinder.Draw();
 
  // Next, the cube is drawn unconditionally, but the samples which passed the depth test are counted.
  GL.BeginQuery( QueryTarget.SamplesPassed, MyOcculsionQuery );
  MyCube.Draw();
  GL.EndQuery( QueryTarget.SamplesPassed );
 
  // depending on whether any sample passed the depth test, the sphere is drawn.
  GL.NV.BeginConditionalRender( MyOcculsionQuery, NvConditionalRender.QueryWaitNv );
  MySphere.Draw();
  GL.NV.EndConditionalRender();
 
  this.SwapBuffers();
}

Although the running program might only show a single object on screen (the cylinder), the cube is always drawn too. Only drawing of the sphere might be skipped, depending on the outcome of the occlusion query used for the cube.

Please note that this is not the standard case how to use occlusion query. The most common way to use them is drawing a simple bounding volume (of a more complex object) to determine whether samples passed and only draw the complex object itself, if the bounding volume is not occluded. For example: Drawing a character with skeletal animation is usually expensive, to determine whether it should be drawn at all, a cylinder can be drawn using an occlusion query and the character is only drawn if the cylinder is not occluded.