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:
- Multisampling Enabled: The active framebuffer must be configured with multisampling (MSAA) with more than one sample per pixel.
- Per-Sample Shading Active: Fragment shaders
typically execute once per pixel by default, even when multisampling is
enabled. Accessing
gl_SamplePositionor declaring fragment inputs with thesampleinterpolation 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.