# Bilinear Interpolation

This topic is 2752 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all,

I'm revisiting some code that has been bugging me for a long time. I need to do bilinear interpolation manually in my fragment shader and I use the following code:

 /* * Bilinear Filtering * * In order to get this working on ATI, the number of operations is * reduced by putting everything into vec4's. uv_top holds the UV * coordinates for the top two texels (.xy=left, .zw=right) and uv_bot * is for the lower two. */ // Compute fractional blending factor, r, and lower left corner of texel 0 uv_bot.xy = gl_TexCoord[0].st-vec2(0.5,0.5); // move into the lower left blending texel r = uv_bot.xy-floor(uv_bot.xy); // fractional part uv_bot.xy = floor(uv_bot.xy); // integral part // Compute texel coordinates uv_bot.xy += vec2(0.5,0.5); // offset to center of pixel (shouldn't be needed but it fixes a lot of glitches, esp. on Nvidia) uv_bot.zw = uv_bot.xy + vec2(1.0,0.0); // compute coordinates of the other three neighbors uv_top = uv_bot + vec4(0.0,1.0,0.0,1.0); // Compute the properly wrapped texel coordinates uv_top = WrapTexelCoords(uv_top,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw)); uv_bot = WrapTexelCoords(uv_bot,vec4(fsSubTexture.xy,fsSubTexture.xy),vec4(fsSubTexture.zw,fsSubTexture.zw), vec4(fsTexParams.zw,fsTexParams.zw)); // Fetch the texels and blend them c[0]=texture2D(textureMap,uv_bot.xy); // bottom-left (base texel) c[1]=texture2D(textureMap,uv_bot.zw); // bottom-right c[2]=texture2D(textureMap,uv_top.xy); // top-left c[3]=texture2D(textureMap,uv_top.zw); // top-right fragColor = c[0]*(1.0-r.s)*(1.0-r.t) + c[1]*r.s*(1.0-r.t) + c[2]*(1.0-r.s)*r.t + c[3]*r.s*r.t; 

The problem is, I can't really account for the "uv_bot.xy+=vec2(0.5,0.5);" statement. I have set my texture map to use GL_NEAREST sampling, which, if my understanding is correct, will sample a texel color even if the coordinate is at the bottom-left of the texel. Nevertheless, this offset into the center of the texel (note that it is normalized to [0,1] later by WrapTexelCoords()) is absolutely necessary, otherwise unwanted bleeding into adjacent texels occurs.

What the code above basically does is:

1. Locate the lower-left pixel of the four pixel set we will be interpolating. Subtracting 0.5,0.5 puts us somewhere in there.
2. The fractional part of this will be used in our weighting factors later on.
3. The integral part (floor) references the lower left pixel.
4. The positions of the adjacent three pixels can be readily computed.

Neglecting the floor() operation for the lower-left pixel does not solve the problem, by the way.

I'm hoping to find a better way to do this. Seems like it should be doable in a much simpler, more compact, and more optimal fashion...

Any ideas?

Thanks!

1. 1
2. 2
Rutin
22
3. 3
4. 4
frob
17
5. 5

• 9
• 33
• 13
• 12
• 10
• ### Forum Statistics

• Total Topics
632577
• Total Posts
3007157

×