What follows is a review of texture addressing and sampling techniques, provided as a supplement to the article "Directly Mapping Texels to Pixels".

Textures are always linearly addressed from (0.0, 0.0) at the top-left corner to (1.0, 1.0) at the bottom-right corner. Figure 7a shows the UV coordinate space of a 4x4 texture:

Textures are usually represented as if they were composed of solid blocks of color, but it's actually more correct to think of textures the same way you should think of the raster display: Each texel is defined at the exact center of a grid cell, as shown in Figure 7b:

If I ask the texture sampler for this texture's color at UV coordinates (0.375, 0.375) I'll get solid red (255, 0, 0). That makes perfect sense because the exact center of the red texel cell is at UV (0.375, 0.375). What if I ask the sampler for the texture's color at UV (0.25, 0.25)? That's not quite as easy, because the point at UV (0.25, 0.25) lies at the exact corner of 4 texels.

The simplest scheme is simply to have the sampler return the color of the closest texel; this is called Point filtering, and is usually undesirable due to grainy or blocky results. Point-sampling our texture at UV (0.25, 0.25) shows another subtle problem with nearest-point filtering: there are four texels equidistant from the sampling point, so there's no single nearest texel. One of those four texels will be chosen as the returned color, but the selection depends on how the coordinate is rounded, which may introduce tearing artifacts (see the Nearest-Point Sampling article in the SDK). 

A slightly more accurate and more common filtering scheme is to calculate the weighted average of the 4 texels closest to the sampling point; this is called Bilinear filtering, and the extra computational cost is usually negligible because this routine is implemented in modern graphics hardware. Here are the colors we get at a few different sample points using bilinear filtering:


UV: (0.5, 0.5)

This point is at the exact border between red, green, blue, and white texels. The color the sampler returns is gray:

  0.25 * (255, 0, 0)
  0.25 * (0, 255, 0) 
  0.25 * (0, 0, 255)
+ 0.25 * (255, 255, 255)
= (128, 128, 128)


UV: (0.5, 0.375)

This point is at the midpoint of the border between red and green texels. The color the sampler returns is yellow-gray (note that the contributions of the blue and white texels are scaled to 0):

  0.5 * (255, 0, 0)
  0.5 * (0, 255, 0) 
  0.0 * (0, 0, 255)
+ 0.0 * (255, 255, 255)
= (128, 128, 0)


UV: (0.375, 0.375)

This is the address of the red texel, which is the returned color (all other texels in the filtering calulcation are weighted to 0): 

  1.0 * (255, 0, 0)
  0.0 * (0, 255, 0) 
  0.0 * (0, 0, 255)
+ 0.0 * (255, 255, 255)
= (255, 0, 0)


Compare these calculations against Figure 7c, which shows what we'll get if we perform the bilinear filtering calculation at every texture address across the 4x4 texture:
Return to "Directly Mapping Texels to Pixels"