Texture magnifiaction filtering


I’m writing a prgram that involves zooming textures so one texture map pixel is quite large on screen. At the moment I’m using the default bilinear filtering, which doesn’t look nearly as good as the bicubic filtering I see in direct3d games.

Is there a way to get bicubic filtering in opengl? (I’m using it on Windows 98)

Thanks in advance,


with unextended gl, no.
unfortunately, afaik there’s no extension for bicubic filtering.

…i didn’t know that D3D has this capability: could you point me to?


Sorry, I don’t know where to find that on the web - I’m just going by the very smooth magnification that I see in direct 3d games!

By the way … a question … how do bicubic filtering differ from bilinear?

AFAIK, the main difference is the smoothness of the transistions between magnified pixels of the texture. I find the bilinear (GL_LINEAR) filtering still looks pretty blocky, with the texels looking rectangular…

Bicubic filtering (I hope that’s the right name ) makes the transistions much smoother - you really can’t see where one texture pixel starts and the other ends.

I’ve just looked in the Direct3D documentation and it says bicubic filtering’s not supported either… is there a way that I’ve missed to make the magnification filtering any smoother?

[This message has been edited by nickL (edited 05-28-2000).]

mainly, in realtime CG, there are three types of filters: nearest, linear and cubic.

nearest, also known as point sampling, simply takes one sample: blocky textures.

the linear filter interpolates linearly (it lerps) two samples (4 if bilinear), so it is smoother than point sampling, but it has a discontinuous 1st-derivative.
it turn out that you can easily see the transitions between texels as crossing lines, wich perception is amplified by our viewing system: the mach banding effect.

the cubic filter uses 4 samples (16 if bicubic!!) but it has a continuous 1st-derivative.
that’s why bicubic interpolated images appear good: our visual system is not triggered (well, not as in linear filtering)to do edge-enhancement, wich is what there’s under mach banding.

the only thing you can do is to pre-smooth your texture, but i’m almost sure you’ve already tried to…


Ok, thanks, but I was wondering more about the actual equations used to implement it. I know how to do nearest and bilinear, but how is the bicubic filtering actually calculated?

Thanks, I never thought of smoothing the texture - it looks much better now

you’re welcome

to do cubic interpolation (i call it cerp) i use this function:

float cerp( float a, float b, float c, float d, float x ) {
float p=(d-c)-(a-b);
float q=(a-b)-p;
float r=c-a;
return x*(x*(x*p+q)+r)+b;

a,b,c,d values to be interpolated.
x interpolation parameter 0…1

when x=0, the function returns b.
when x=1, the function returns c.

winamp, for instance, uses a piecewise cubic for the equalizer… i use cerp as a primitive to generate 3D perlin noise for plasmas, landscapes, automatic movements ratios or smooth paths… almost everything!

oh, this is 1D.
in 2D, you should:

a=cerp( v[0][0], v[1][0], v[2][0], v[3][0], x );
b=cerp( v[0][1], v[1][1], v[2][1], v[3][1], x );
c=cerp( v[0][2], v[1][2], v[2][2], v[3][2], x );
d=cerp( v[0][3], v[1][3], v[2][3], v[3][3], x );
v=cerp( a, b, c, d, y );

quite many calcs!
v holds the interpolated value.


[This message has been edited by dmy (edited 05-28-2000).]

Hmm … that’s a massive work for a graphic adapter to do … i guess i get why it’s not commonly supported.
This x parameter, how is it chosen? Has it something to do with the distance to each pixel which is filters between?