Skip to main content
GameDev.net gamedev.net
🔒 Locked

bicubic interpolation code?

Started by avocados Aug 23, 2009 at 7:15 PM 7 replies 5.6k views
Original Post
avocados
avocados
The math is beyond me right now, can anyone point me towards a working c function?
s_p_oneil
s_p_oneil
Cubic is the same as linear, but as you interpolate values in a line from 0 to 1, you apply a simple function to convert the line into a smooth curve. The cubic function in my Cg shaders looks like this:

// Cubic smoothing, yields C1 continuous curve from 0..1float cubic(float r) { return r*r*(3.0-2.0*r); }float2 cubic(float2 r) { return r*r*(3.0-2.0*r); }float3 cubic(float3 r) { return r*r*(3.0-2.0*r); }float4 cubic(float4 r) { return r*r*(3.0-2.0*r); }


Then you would use it kind of like this (I cut and paste from a larger shader, and changed some things, so I doubt this would compile without tweaks):
float4 bicubic(sampler2D t, float2 coord) {  int2 n = floor(coord);  float2 r = fract(coord);  float2 w = cubic(r);  return lerp(    lerp(tex2Dfetch(t, int2(n.x,n.y)), tex2Dfetch(t, int2(n.x+1,n.y)), w.x),    lerp(tex2Dfetch(t, int2(n.x,n.y+1)), tex2Dfetch(t, int2(n.x+1,n.y+1)), w.x), w.y);


If you remove the call to cubic, you get bilinear interpolation. All the cubic() call really does is change the distribution of lookup points between two texels. Where linear would give you noticeable lines, cubic smooths them out a bit (though they are usually still noticeable).

EDIT: Sorry it's not in C, but this is what I had on hand, and it shouldn't be too hard for you to convert it.
avocados
avocados
Bilinear filtering doesn't look so hot, I really need to find something better.
bzroom
bzroom
If you're using mipmaps i think you want tri-linear.
PolyVox
PolyVox
Quote:
Original post by s_p_oneil
Cubic is the same as linear, but as you interpolate values in a line from 0 to 1, you apply a simple function to convert the line into a smooth curve. The cubic function in my Cg shaders looks like this:


Don't want to drag this off topic as the OP seems to be looking for a CPU solution, but are you aware that in GPU Gems 2 there is an article (Chapter 20) on implementing cubic filtering in terms of linear filters? You can get it for free on the NVidia website. Also you might find this interesting:

http://forums.nvidia.com/index.php?s=1b5ab4d23263c15f993c03ca75ad94bc&showtopic=79122
avocados
avocados
Oops, I meant bilinear interpolation doesn't work well. This project is not in a 3d API. I need to smoothly scale noise for some perlin noise in procedural textures.
s_p_oneil
s_p_oneil
Quote:
Original post by avocados
Oops, I meant bilinear interpolation doesn't work well. This project is not in a 3d API. I need to smoothly scale noise for some perlin noise in procedural textures.


If you're using the original Perlin noise implementation, it already has cubic interpolation built into it (and requires a much smaller buffer in memory thanks to its lattice function). The improved Perlin noise uses quintic, which does the same thing but replaces the cubic() function with a slightly more expensive function. Quintic is a bit smoother at the edges, but IMO produces a curve that doesn't look as good.

If you're using a simple 2D or 3D buffer of random values and trying to interpolate between those values yourself, then you should start by implementing cubic interpolation as I've indicated and see how it looks. Depending on what you're using the noise for, you may find that cubic is not good enough (it wasn't good enough for my needs). The best method I've found for something like that is Catmull-Rom spline interpolation (which I've implemented in C and Cg). It is significantly more expensive, but gives perfectly smooth results.
s_p_oneil
s_p_oneil
Quote:
Original post by PolyVox
Don't want to drag this off topic as the OP seems to be looking for a CPU solution, but are you aware that in GPU Gems 2 there is an article (Chapter 20) on implementing cubic filtering in terms of linear filters? You can get it for free on the NVidia website. Also you might find this interesting:


Thanks for the tip, but I wrote chapter 16 of that book. NVidia sent me 6 copies of it. ;-)
PolyVox
PolyVox
Quote:
Original post by s_p_oneil
Quote:
Original post by PolyVox
Don't want to drag this off topic as the OP seems to be looking for a CPU solution, but are you aware that in GPU Gems 2 there is an article (Chapter 20) on implementing cubic filtering in terms of linear filters? You can get it for free on the NVidia website. Also you might find this interesting:


Thanks for the tip, but I wrote chapter 16 of that book. NVidia sent me 6 copies of it. ;-)


Ah, actually I did wonder if it was you after I posted ;-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.