How gl_SampleID Identifies Samples in GLSL
This article explains how the built-in gl_SampleID input
variable operates within OpenGL Shading Language (GLSL) to identify
specific sub-pixel samples. It covers the transition from standard
pixel-frequency shading to per-sample frequency shading, the zero-based
indexing mechanism used by the graphics pipeline, and how
gl_SampleID interacts with related sample-rate built-ins
during multisample anti-aliasing (MSAA) rendering.
The Role of gl_SampleID
In GLSL, gl_SampleID is a built-in fragment shader input
variable defined as a signed integer (in int gl_SampleID;).
Its primary role is to serve as an integer index that uniquely
identifies the sub-pixel sample currently being processed by the
fragment shader instance.
In standard rendering workflows using Multisample Anti-Aliasing
(MSAA), the fragment shader executes only once per pixel covered by a
geometric primitive, and the resulting color is shared across all
covered sub-pixel sample points. However, when sample-specific
operations or custom anti-aliasing algorithms are required, the fragment
shader must evaluate each sub-pixel sample point individually. The
gl_SampleID variable provides the shader with direct
knowledge of which distinct sample point within the pixel grid is being
shaded.
How Identification Works
When a multisample framebuffer is bound, each pixel is divided into a
fixed number of sub-pixel sample positions, determined by the total
sample count (accessible in GLSL via the gl_NumSamples
built-in variable).
- Zero-Based Indexing: The graphics hardware assigns
an integer index to each sample point, starting at
0and ending atgl_NumSamples - 1. If an 8x MSAA configuration is active, the samples are indexed sequentially from0through7. - Sub-Pixel Assignment: Each integer index
corresponds to a specific fixed sub-pixel offset within the bounds of
the pixel. When the GPU schedules a fragment thread to evaluate a
specific sample location, it loads that sample's index directly into the
gl_SampleIDregister for that invocation. - Execution Context: The current execution thread can
then use this integer directly to index into arrays, determine
sample-specific parameters, or fetch data from multisample textures via
the
texelFetchfunction.
Implicit Activation of Sample-Rate Shading
Using gl_SampleID modifies the execution frequency of
the fragment shader:
- Triggering Per-Sample Execution: Simply reading
from
gl_SampleIDanywhere inside the fragment shader implicitly forces the GPU to execute the fragment shader at sample frequency rather than pixel frequency. - Invocation Multiplicity: Instead of running once
per covered pixel, the shader automatically runs once per covered
sample. For a 4x MSAA buffer where all four samples are covered by a
triangle, the fragment shader executes four separate times for that
single pixel, with
gl_SampleIDsequentially resolving to0,1,2, and3. - Performance Impact: Because this increases the
total fragment shader invocations up to the number of samples per pixel,
relying on
gl_SampleIDsubstantially increases GPU workload compared to standard MSAA.
Relationship with gl_SamplePosition
While gl_SampleID identifies which sample is
being evaluated by index, it does not directly convey the geometric
coordinates of that sample. To obtain the physical sub-pixel offset,
gl_SampleID is often used alongside
gl_SamplePosition, a vec2 containing the
two-dimensional sub-pixel coordinates of the current sample scaled to
the range [0.0, 1.0], where (0.5, 0.5)
represents the exact center of the pixel. Together, these variables
allow shaders to perform precise procedural filtering, custom
anti-aliasing resolves, and sample-correct lighting evaluations.