SamplerCubeShadow Depth Comparison in GLSL

In OpenGL Shading Language (GLSL), samplerCubeShadow facilitates hardware-accelerated omnidirectional shadow mapping by performing an automated depth comparison between a fragment's distance from a light source and the depth stored in a cubemap. Instead of retrieving the raw depth value written during the shadow pass, the sampler evaluates a comparison function against a provided reference depth and returns a visibility factor ranging from 0.0 (fully shadowed) to 1.0 (fully lit).

Lookup Coordinates and the Reference Value

When sampling a shadow cubemap via the GLSL texture() function, the coordinate argument is passed as a four-component vector (vec4 P):

  • P.xyz (Direction Vector): An unnormalized direction pointing from the point light source to the fragment in world or view space. The hardware evaluates the major axis of this vector to identify which of the six cube faces (+X, -X, +Y, -Y, +Z, or -Z) to sample, then projects the remaining axes to compute 2D UV coordinates on that face.
  • P.w (Reference Depth): The reference value representing the fragment's calculated distance from the light. This value must be normalized to match the \([0.0, 1.0]\) range format used when rendering the shadow cubemap depth buffer.

Comparison Mechanics

For the depth comparison to execute automatically, the texture must have its GL_TEXTURE_COMPARE_MODE parameter configured to GL_COMPARE_REF_TO_TEXTURE on the host side. The actual comparison is governed by GL_TEXTURE_COMPARE_FUNC:

  1. Sampling: The hardware projects P.xyz onto the appropriate cube face and retrieves the stored depth (\(D_{stored}\)) at those coordinates.
  2. Comparison: The hardware compares the reference depth (\(P.w\) or \(D_{ref}\)) against \(D_{stored}\) using the specified comparison function (typically GL_LEQUAL or GL_LESS).
  3. Result Generation:
    • If using GL_LEQUAL, the test evaluates \(D_{ref} \le D_{stored}\).
    • If the test passes, the fragment is at or closer to the light than the nearest occluder, yielding a result of 1.0 (unshadowed).
    • If the test fails, an occluder lies between the light and the fragment, yielding 0.0 (shadowed).

Hardware Percentage-Closer Filtering (PCF)

When the cubemap's GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER are set to GL_LINEAR, the hardware performs Percentage-Closer Filtering (PCF) automatically. Rather than linearly interpolating the raw depth values of the four adjacent texels, the hardware:

  1. Compares \(P.w\) individually against each of the neighboring texels around the projected coordinate.
  2. Bilaterally interpolates the binary results of these individual comparisons.

This produces a fractional floating-point value between 0.0 and 1.0 at shadow borders, creating smoother transitions and reducing aliasing along shadow edges with minimal performance overhead.