Understanding gl_SamplePosition in GLSL

In the OpenGL Shading Language (GLSL), gl_SamplePosition is a built-in fragment shader input variable that supplies the exact sub-pixel coordinates of the current sample point within a pixel. This article explains the data provided by gl_SamplePosition, how its coordinate space is defined, the conditions required to use it, and how it benefits advanced multisampling techniques in graphical rendering.

What gl_SamplePosition Represents

The gl_SamplePosition variable is a two-component floating-point vector (vec2) available during multisample fragment processing. It provides the exact spatial location of the specific sample currently being evaluated, relative to the boundaries of the corresponding pixel.

Rather than treating a pixel as an indivisible point or a single center location, multisampling requires fragments to evaluate multiple discrete locations across the surface of a pixel. gl_SamplePosition explicitly returns these sub-pixel positions.

Coordinate Space and Bounds

The values provided by gl_SamplePosition are normalized within the range [0.0, 1.0] along both axes:

  • Origin (0.0, 0.0): Corresponds to the lower-left corner of the pixel area.
  • Pixel Center (0.5, 0.5): Corresponds to the geometric center of the pixel.
  • Upper Limit (1.0, 1.0): Corresponds to the upper-right corner of the pixel area.

Because sample placement patterns vary by hardware architecture and antialiasing modes (such as standard grid, rotated grid, or jittered sampling), the values in gl_SamplePosition reflect the specific implementation chosen by the graphics driver and GPU for that sample.

Prerequisites and Activation

gl_SamplePosition is introduced in GLSL 4.00 (or earlier via the GL_ARB_sample_shading extension). To read meaningful sub-pixel values from it, the rendering pipeline must meet specific criteria:

  1. Multisampling Enabled: The active framebuffer must be configured with multisampling (MSAA) with more than one sample per pixel.
  2. Per-Sample Shading Active: Fragment shaders typically execute once per pixel by default, even when multisampling is enabled. Accessing gl_SamplePosition or declaring fragment inputs with the sample interpolation qualifier forces per-sample frequency execution, meaning the fragment shader runs once for every covered sample rather than once per primitive per pixel.

Practical Applications

Access to gl_SamplePosition is essential for tasks requiring sub-pixel accuracy, including:

  • Custom Resolving: Implementing custom filters when blending multisample render targets into a final single-sample image.
  • Analytical Anti-Aliasing: Evaluating procedural edges, vector graphics, or Signed Distance Fields (SDFs) with high precision against the exact physical sample point.
  • Sub-Pixel Jitter Correction: Compensating for camera jitter or spatial offsets in temporal antialiasing (TAA) implementations.