2
\$\begingroup\$

When looking for implementations of bilinear filtering online, all the ones I can find seem to just pick the current pixel, and the three pixels to the bottom and right side of the current pixel.

However, is this even correct, or do you actually have to get the nearest neighbors to the current pixel (from the 8 surrounding pixels) depending on the texture coordinate?

Also, how would I select between the 8 options as efficiently as possible in shaders?

\$\endgroup\$
  • \$\begingroup\$ I am no expert but I think it's used to create a new pixel color from four existing pixels colors. That is why you only need 4 pixels. \$\endgroup\$ – wolfdawn Jan 30 '14 at 20:07
2
\$\begingroup\$

For bilinear filtering, you have to pick the four pixels whose centers are closest to the sample point. (The term "current pixel" is imprecise. Pixels are discrete points, and when you do a texture lookup you provide a point in continuous UV coordinates.)

Since the pixels are arranged on a grid, finding the four whose centers are nearest is easy. First you convert from UV space to pixel coordinates by multiplying by (width, height). In that space, the pixel centers are at coordinates like 0.5, 1.5, 2.5, etc. So, if you subtract 0.5 from the pixel coordinates and then split the integer and fractional components, you have the four nearest pixels (from the integer part, plus offsets by (1,0), (0,1) and (1,1)) plus the coefficients for the bilinear interpolation (from the fractional part).

You do not have to consider 8 neighbors because you can always figure out the 4 nearest pixels directly this way.

\$\endgroup\$
  • \$\begingroup\$ also consider that linear maths (classic interpolation) doesn't work great against perception. it is better to interpolate in gamma space. sRGB texture formats will help with that. \$\endgroup\$ – v.oddou Jan 31 '14 at 2:52
  • 1
    \$\begingroup\$ also spacially, nothing is mathematically defined for sure to be "the one way". this is signal theory and many people suggest other methods for upscaling than bilinear filter that will work perceptually better. linear filtering involves lots of second derivative discontinuities which the eye is sensitive to, not to mention the non-improvement of stair-effect on aliased diagonals etc.. \$\endgroup\$ – v.oddou Jan 31 '14 at 2:56
1
\$\begingroup\$

You know the factorial component of the UV values. It is represented by the black square's center in the second image; Based on its corners' positions (each 0.5 pixels away in both axises) you pick the four closest four pixels.

This is the texture up close (4x4 pixels)

enter image description here

Now see how an uneven portion of each pixel is overlapped by the black square. Using the relative percentage of the surface it covers of each of the nearest four pixels you"ll mix the colors of these pixels (For instance in this example we get a lot of orange, only a little bit of dark blue and so forth).

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Thanks, but that is not what I'm asking for. My question is whether it's correct to always pick the three neighbours to the bottom, bottom right, and right, or whether you have to actually select the 4 nearest neighbors from the 8 neighbors around the pixel targeted by the texture coordinate. And if the latter is correct, how to select between the 8 neighbors effectively in shaders (without lots of branching, etc.) \$\endgroup\$ – TravisG Jan 30 '14 at 20:28
  • \$\begingroup\$ You actually pick four pixels. The upper left corner is not a given. What you call picking different neighbors, is actually picking another group of four pixels or another upper left pixel if you will. -> I will edit the answer to better suit your question. \$\endgroup\$ – wolfdawn Jan 30 '14 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.