Bilinear Interpolation

When sampling a texel from a texture that has been re-sized (which is nearly always the case in 3D rendering) you need to use some kind of filter to select what result you should get. Bilinear interpolation uses the four nearest neighbors to interpolate an average texel value.

Bilinear Interpolation

This is a built in filter in OpenGL and to activate it you set the following lines when setting up a texture:

// set the minification filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
// set the magnification filter
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

If you for some reason wants to do bilinear interpolation manually in a shader then the function to do so looks like the following in GLSL. Note that in vertex shaders you have to do manual bilinear interpolation between texture samples.

const float textureSize = 512.0; //size of the texture
const float texelSize = 1.0 / textureSize; //size of one texel 
 
vec4 texture2DBilinear( sampler2D textureSampler, vec2 uv )
{
    // in vertex shaders you should use texture2DLod instead of texture2D
    vec4 tl = texture2D(textureSampler, uv);
    vec4 tr = texture2D(textureSampler, uv + vec2(texelSize, 0));
    vec4 bl = texture2D(textureSampler, uv + vec2(0, texelSize));
    vec4 br = texture2D(textureSampler, uv + vec2(texelSize , texelSize));
    vec2 f = fract( uv.xy * textureSize ); // get the decimal part
    vec4 tA = mix( tl, tr, f.x ); // will interpolate the red dot in the image
    vec4 tB = mix( bl, br, f.x ); // will interpolate the blue dot in the image
    return mix( tA, tB, f.y ); // will interpolate the green dot in the image
}

Here’s a magnification of a texture using using three different types of filters. The texture is mapped on a sphere and the viewport has been zoomed in on a small part of it.

Nearest Neigbour  (OpenGL fixed function implementation)

Nearest Neigbor filter

Bilinear Interpolation (OpenGL fixed function implementation)

Bilinear Interpolation OpenGL

Bilinear Interpolation (GLSL implementation, the code above)

Bilinear Interpolation GLSL

Some information about OpenGL texture mapping and how to set the filtering properties:
http://www.nullterminator.net/gltexture.html

Here’s some discussion why you should not always use bilinear interpolation:
http://gregs-blog.com/2008/01/14/how-to-turn-off-bilinear-filtering-in-opengl/

Link to a bilinear interpolation function for DirectX:
http://www.catalinzima.com/?page_id=85

Article on GameDev.net about bilinear filtering:
http://www.gamedev.net/reference/articles/article669.asp

Please share:
  • Print this article!
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Current
  • LinkedIn
  • Live
  • MySpace
  • Netvibes
  • StumbleUpon
  • Twitter
  • Reddit
  • Technorati
  • Yahoo! Bookmarks

3 thoughts on “Bilinear Interpolation

  1. Pingback: Twofold Secret / We make games that we love

  2. Vern Jensen

    Thanks for this! I plugged it into my code and it just worked…. nice! I needed to do my own bilinear interpolation because I’m using GL_FLOAT in OpenGL ES 2.0, which is only supported via an extension, and does NOT support GL_LINEAR as a mag filter in this instance. Doing my own is the only solution to get things working the way I want them to. Great post!

    Reply
  3. Pingback: MSc Computer Games & Entertainment » Blog Archive » Maths&Gfx1: Coursework2

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>