How GLSL textureGather Samples Four Texels
This article provides a technical overview of the
textureGather function in GLSL, detailing how the GPU
extracts four neighboring texels simultaneously in a single texture
lookup. It covers the underlying hardware addressing mechanics, the
specific channel selection process, the exact ordering of the returned
four-component vector, and the primary rendering scenarios where this
instruction delivers optimal performance over standard texture
fetches.
The Mechanism Behind textureGather
In traditional texture mapping, the GLSL texture()
function performs bilinear interpolation across four adjacent texels to
return a single blended color vector. Conversely,
textureGather bypasses the fixed-function interpolation
hardware. Instead, it directly retrieves the four raw texel values that
would have contributed to that bilinear footprint and returns them
simultaneously inside a single vec4.
When a 2D texture coordinate \((u,
v)\) is passed to textureGather, the GPU converts
the normalized coordinates into absolute texel-space coordinates by
multiplying them by the texture dimensions and subtracting \(0.5\). The base texel index \((i, j)\) is computed by flooring these
continuous coordinates:
\[i = \lfloor u \times \text{width} - 0.5 \rfloor\] \[j = \lfloor v \times \text{height} - 0.5 \rfloor\]
The four texels making up the \(2 \times 2\) sampling footprint are defined by the coordinate pairs:
- Bottom-left: \((i, j)\)
- Bottom-right: \((i + 1, j)\)
- Top-right: \((i + 1, j + 1)\)
- Top-left: \((i, j + 1)\)
Component Selection
Because a standard GLSL return value is limited to a four-component
vector (vec4), textureGather cannot return
full RGBA data for all four texels simultaneously. Instead, it extracts
one designated color component from all four texels.
The component sampled is determined by an optional integer parameter
comp:
0: Red channel (default if omitted)1: Green channel2: Blue channel3: Alpha channel
For depth textures, textureGather automatically samples
the depth component.
Texel Layout in the Returned Vector
The four harvested values are packed into the destination
vec4 in a counter-clockwise order starting from the
upper-left texel relative to the coordinate origin. The OpenGL and GLSL
specifications define the component mapping as follows:
.xcomponent: Texel at \((i, j + 1)\) [Top-Left].ycomponent: Texel at \((i + 1, j + 1)\) [Top-Right].zcomponent: Texel at \((i + 1, j)\) [Bottom-Right].wcomponent: Texel at \((i, j)\) [Bottom-Left]
This specific mapping allows shader developers to know the spatial orientation of each texel without performing individual coordinate offsets.
Practical Applications and Efficiency
Sampling four texels in a single instruction reduces texture cache
pressure and minimizes memory bandwidth bottlenecks. Rather than issuing
four separate texelFetch or point-sampled
texture calls, the GPU issues one memory transaction to
fetch the quad footprint.
Key use cases include:
- Percentage-Closer Filtering (PCF): In shadow
mapping,
textureGatherallows testing four depth samples against the light-space depth in parallel, followed by custom weighting in shader logic. - Custom Bilinear and Bicubic Filtering: Shaders requiring manual interpolation weights (such as categorical textures or normal maps where standard hardware blending corrupts mathematical correctness) can reconstruct filters manually using fractional coordinate weights.
- Screen-Space Ambient Occlusion (SSAO) and Edge Detection: Depth buffer discontinuities and surface normal edges can be analyzed rapidly across a \(2 \times 2\) neighborhood without multiple fetch instructions.