05. Depth Test

A commonly used logical buffer in OpenGL is the Depth buffer, often called Z-Buffer. The name was chosen due to X and Y being used to describe horizontal and vertical displacement on the screen, so Z is used to measure the distance perpendicular to the screen.

The general purpose of this buffer is determining whether a fragment is occluded by a previously drawn pixel. I.e. If the fragment in question is further away from the eye than an already existing pixel, the fragment cannot be visible and is discarded.

In order to use the Depth buffer, the window-system provided framebuffer - or the Depth attachment of a FBO - must explicitly contain a logical Depth buffer. If there is no Depth buffer, the fragment is always passed to the next pipeline stage.

DepthTest functionality is enabled and disabled with EnableCap.DepthTest

GL.Enable( EnableCap.DepthTest );
GL.Disable( EnableCap.DepthTest ); // default

The value used by GL.Clear() commands can be set through:

GL.ClearDepth( double ); // 1.0 is the default, Range: [0.0 .. 1.0]

If DepthTest is enabled, writing to the Depth buffer can be toggled by a boolean flag.

GL.DepthMask( bool ); // true is the default

The command GL.DepthFunc( func ) is used to specify the comparison method used whether a fragment is closer to the eye than the existing pixel it is compared to.

Function of the test can have the following values, the default is DepthFunction.Less.

  • DepthFunction.Always - Test will always succeed.
  • DepthFunction.Never - Test will never succeed.
  • DepthFunction.Less - Test will succeed if ( fragment depth < pixel depth )
  • DepthFunction.Lequal - Test will succeed if ( fragment depth <= pixel depth )
  • DepthFunction.Equal - Test will succeed if ( fragment depth == pixel depth )
  • DepthFunction.Notequal - Test will succeed if ( fragment depth != pixel depth )
  • DepthFunction.Gequal - Test will succeed if ( fragment depth >= pixel depth )
  • DepthFunction.Greater - Test will succeed if ( fragment depth > pixel depth )

The command GL.DepthRange( near, far ) is used to define the minimum (near plane) and maximum (far plane) z-value that is stored in the Depth Buffer. Both parameters are expected to be of double-precision floating-point and must lie within the range [0.0 .. 1.0].

It is allowed to call GL.DepthRange( 1.0, 0.0 ), there is no rule that must satisfy ( near < far ).

For an in-depth explanation how the distribution of z-values in the Depth buffer works, please read Depth buffer - The gritty details.

State Queries

To determine whether DepthTest is enabled or disabled, use Result = GL.IsEnabled( EnableCap.DepthTest );

The bits available in the Stencil Buffer can be queried by GL.GetInteger( GetPName.DepthBits, ... );

The value set by GL.ClearDepth() can be queried by GL.GetFloat( GetPName.DepthClearValue, ... );

The boolean set by GL.DepthMask() can be queried by GL.GetBoolean( GetPName.DepthWritemask, ... );

The Depth comparison function can be queried with GL.GetInteger( GetPName.DepthFunc, ... );

The Depth range can be queried with GL.GetFloat( GetPName.DepthRange, ... ); // returns an array