Understanding GL_CLAMP_TO_BORDER in GLSL
This article provides an overview of how the
GL_CLAMP_TO_BORDER texture wrap mode operates when sampling
textures in OpenGL Shading Language (GLSL). It explains the interaction
between CPU-side texture parameter configuration, the underlying
hardware texture sampling unit, filtering mechanics, and how GLSL
shaders transparently handle out-of-bounds coordinates.
How GL_CLAMP_TO_BORDER Works in GLSL
In GLSL, shader code does not require any special functions or
conditional statements to handle GL_CLAMP_TO_BORDER. When
using standard texture sampling functions—such as
texture(), textureLod(), or
texelFetch()—the texture hardware handles coordinate
evaluation automatically.
When a texture coordinate falls outside the normalized range of
[0.0, 1.0], the hardware texture sampling unit detects that
the coordinate has exceeded the boundary. Instead of clamping to the
outer edge pixels (GL_CLAMP_TO_EDGE) or repeating the
pattern (GL_REPEAT), it returns a constant predefined
border color.
Specifying the Border Color
The border color is a state configured on the CPU side through the OpenGL API, not inside the GLSL shader itself. It is assigned to a texture object or a sampler object:
float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; // RGBA
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);When a sampler in GLSL samples from this texture with coordinates
such as vec2(-0.2, 0.5) or vec2(1.5, 1.2), the
returned vec4 will be
vec4(0.0, 0.0, 0.0, 1.0).
Impact of Texture Filtering
The exact value returned near the edges depends on the minification
and magnification filters (GL_TEXTURE_MIN_FILTER and
GL_TEXTURE_MAG_FILTER):
- GL_NEAREST: The texture unit chooses the nearest texel. If the sample coordinate maps past the outer boundary of the outermost texel centers, the exact border color is returned immediately.
- GL_LINEAR: The texture unit linearly interpolates between the edge texels and the border color across a half-texel wide strip along the perimeter. Coordinates near the border smoothly transition into the border color rather than switching abruptly.
Special Texture Types
- Integer Textures: When using signed or unsigned
integer formats (such as
isampler2Dorusampler2D),glTexParameterIivorglTexParameterIuivmust be used to define the border color. Passing standard float values will cause undefined behavior or clamping. - Depth and Shadow Textures: When depth comparison
modes (
GL_COMPARE_REF_TO_TEXTURE) are active, the border color's depth component is used in the comparison operation. This is commonly leveraged in shadow mapping to ensure areas outside the shadow map frustum evaluate consistently as either fully in shadow or fully lit.