GLSL sampler2DRect Coordinate Scaling and Wrapping

Sampling from a sampler2DRect in GLSL differs significantly from standard 2D texture sampling, as it operates on rectangular texture targets (GL_TEXTURE_RECTANGLE). Instead of using normalized floating-point coordinates bounded between 0.0 and 1.0, sampler2DRect relies directly on unnormalized pixel coordinates and imposes strict constraints on texture wrapping modes and mipmapping.

Coordinate Scaling Rules

When sampling from a sampler2DRect, texture coordinates are unnormalized:

  • Pixel-Space Units: The coordinate range spans from 0.0 to width along the horizontal axis (\(s\)) and 0.0 to height along the vertical axis (\(t\)). You do not divide coordinates by the texture dimensions.
  • Texel Centers: Texel centers are located at half-integer offsets. For example, the center of the first texel at the bottom-left is \((0.5, 0.5)\), and the center of the texel at index \((x, y)\) is \((x + 0.5, y + 0.5)\).
  • Direct Texel Addressing: Providing an integer coordinate such as \((1.0, 1.0)\) places the sample directly on the boundary between adjacent texels, which triggers interpolation when linear filtering is enabled.

Wrapping Rules

Rectangular textures do not support standard repeat modes due to hardware and architectural design. The applicable wrapping rules are:

  • Supported Modes: The OpenGL specification restricts GL_TEXTURE_RECTANGLE targets to GL_CLAMP_TO_EDGE and GL_CLAMP_TO_BORDER.
  • Unsupported Modes: Wrapping modes that involve repetition—specifically GL_REPEAT and GL_MIRRORED_REPEAT—are strictly invalid. Setting these modes on a rectangular texture results in an OpenGL error or undefined behavior.
  • Out-of-Bounds Behavior: If sampling coordinates fall outside the range \([0.0, \text{width}]\) or \([0.0, \text{height}]\), the sampler will either clamp to the color of the outermost boundary texels (GL_CLAMP_TO_EDGE) or return the specified constant border color (GL_CLAMP_TO_BORDER).

Beyond scaling and wrapping, rectangular textures enforce two structural constraints:

  • No Mipmapping: Rectangular textures support only a single level of detail (Level 0). Mipmap generation and mipmapped filtering modes (such as GL_LINEAR_MIPMAP_LINEAR) cannot be used. Texture filtering must be configured as either GL_NEAREST or GL_LINEAR.
  • GLSL Sampling Functions: In modern GLSL versions, sampling is performed using the overloaded texture(sampler2DRect, vec2) function. In legacy GLSL versions, the dedicated texture2DRect(sampler2DRect, vec2) function is required.