GLSL: sampler1D vs sampler2D with Height of One
Sampling from a sampler1D versus a
sampler2D with a height of one in GLSL primarily differs in
coordinate dimensionality, filtering behavior, mipmap generation, and
cross-platform compatibility. While both approaches can represent an
identical one-dimensional array of texels in memory,
sampler1D operates strictly along a single axis, whereas a
1xN sampler2D introduces a second axis that requires
explicit coordinate management, alters hardware derivative calculations,
and ensures broader compatibility across graphics APIs.
Coordinate Dimensionality and Syntax
The most immediate difference is the texture coordinate parameter required by the GLSL sampling functions:
sampler1D: Requires a scalar coordinatefloat(e.g.,texture(tex1D, u)).sampler2D: Requires a two-component vectorvec2(e.g.,texture(tex2D, vec2(u, 0.5))).
When querying a 2D texture of size \(N
\times 1\), you must supply a fixed V (or Y) coordinate. To
sample the center of the single row of pixels, this value is typically
set to 0.5. Passing an incorrect V coordinate can introduce
sampling artifacts depending on the texture's wrapping modes.
Filtering and Edge Clamping
Texture filtering behaves differently across the unused dimension:
- 1D Textures: Filtering (linear interpolation) only occurs along the X axis between adjacent texels. There is no concept of a perpendicular axis.
- 2D Textures (\(N \times
1\)): Bilinear filtering considers both the X and Y
axes. If the V coordinate shifts slightly away from
0.5due to floating-point imprecision or custom calculations, the sampler will attempt to interpolate along the Y axis. If the texture wrapping mode is set toGL_REPEATorGL_CLAMP_TO_BORDER, the sampled color might blend with the wrap target or border color instead of retaining the exact texel color. To prevent this, the texture's vertical wrap mode must explicitly be set toGL_CLAMP_TO_EDGE.
Derivatives and Mipmapping
Automatic Level of Detail (LOD) calculations rely on screen-space derivatives:
- Derivatives: For
sampler1D, the GPU calculates screen-space derivatives \(\frac{\partial u}{\partial x}\) and \(\frac{\partial u}{\partial y}\) exclusively on the 1D coordinate. Forsampler2D, derivatives are computed for both coordinates (\(\frac{\partial u}{\partial x}\), \(\frac{\partial u}{\partial y}\), \(\frac{\partial v}{\partial x}\), and \(\frac{\partial v}{\partial y}\)). - Mipmaps: In a true 1D texture, mipmap levels divide the width by two at each step until reaching \(1 \times 1\). For an \(N \times 1\) 2D texture, the mip chain reduces the width while the height remains clamped at \(1\) (\(N \times 1, \frac{N}{2} \times 1, \dots, 1 \times 1\)). While the resulting mip chain structure is identical, the 2D sampler's LOD selection can theoretically be skewed if the V coordinate varies across fragments.
Hardware Execution and Performance
On modern desktop GPUs, dedicated 1D texture hardware is rare. Most
drivers allocate 1D textures as 2D textures internally with a height of
one or as an array layer. Consequently, memory bandwidth, cache hit
rates, and execution speed are virtually identical between the two on
desktop platforms. However, sampler2D incurs a negligible
overhead of passing and interpolating a 64-bit coordinate pair
(vec2) rather than a single 32-bit float
(float).
Platform Compatibility
The choice between the two often comes down to API support:
- OpenGL Desktop: Fully supports
sampler1Dacross all core and compatibility profiles. - OpenGL ES and WebGL: Do not support 1D textures or
sampler1D. In mobile, embedded, and web environments, an \(N \times 1\) texture bound to asampler2Dis the standard and necessary approach for 1D data lookup tables.