Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Create Bi-Cubic and Bi-Linear interpolation with GLSL Shader.

6,548 views
Skip to first unread message

SanS

unread,
Aug 8, 2011, 1:54:11 PM8/8/11
to
Hi all,

Bi-Cubic and Bi-Linear interpolation is implemented with OpenGL.
http://www.codeproject.com/KB/GPU-Programming/GLSLBiCubicInterpolation.aspx

Skybuck Flying

unread,
Aug 9, 2011, 9:06:48 AM8/9/11
to
"SanS" wrote in message
news:6435e426-5b33-4d60...@h25g2000prf.googlegroups.com...

"
Hi all,

Bi-Cubic and Bi-Linear interpolation is implemented with OpenGL.
http://www.codeproject.com/KB/GPU-Programming/GLSLBiCubicInterpolation.aspx
"

Looks like crap to me.

3D Information in the colors is lost, like shading and highlights.

Let the human brain do interpolation I say ;)

Bye,
Skybuck.

hanukas

unread,
Aug 11, 2011, 3:52:41 AM8/11/11
to
On Aug 8, 8:54 pm, SanS <santhos...@gmail.com> wrote:
> Hi all,
>
> Bi-Cubic and Bi-Linear interpolation is implemented with OpenGL.http://www.codeproject.com/KB/GPU-Programming/GLSLBiCubicInterpolatio...

vec4 BiCubic( sampler2D textureSampler, vec2 TexCoord )
{
// ... edit ...
for( int m = -1; m <=2; m++ )
{
for( int n =-1; n<= 2; n++)
{
vec4 vecData = texture2D(textureSampler,
TexCoord + vec2(texelSizeX *
float( m ), texelSizeY * float( n )));
}
}

// ... edit ...
}

You are doing 16 texture2D reads, this is possible to optimize into 4:

vec4 filter(sampler2D texture, vec2 texcoord, vec2 texscale)
{
float fx = fract(texcoord.x);
float fy = fract(texcoord.y);
texcoord.x -= fx;
texcoord.y -= fy;

vec4 xcubic = cubic(fx);
vec4 ycubic = cubic(fy);

vec4 c = vec4(texcoord.x - 0.5, texcoord.x + 1.5, texcoord.y -
0.5, texcoord.y + 1.5);
vec4 s = vec4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x +
ycubic.y, ycubic.z + ycubic.w);
vec4 offset = c + vec4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) /
s;

vec4 sample0 = texture2D(texture, vec2(offset.x, offset.z) *
texscale);
vec4 sample1 = texture2D(texture, vec2(offset.y, offset.z) *
texscale);
vec4 sample2 = texture2D(texture, vec2(offset.x, offset.w) *
texscale);
vec4 sample3 = texture2D(texture, vec2(offset.y, offset.w) *
texscale);

float sx = s.x / (s.x + s.y);
float sy = s.z / (s.z + s.w);

return mix(
mix(sample3, sample2, sx),
mix(sample1, sample0, sx), sy);
}

The trick is a simple one: the area we are sampling from is 4x4. We
break this down into four quadrants, 2x2 each. This means we can
sample each quadrant (2x2) using hardware texture sampler in bilinear
mode. We simply compute texture coordinates so that each texel gets a
correct weight from bicubic function.

We now have four samples. We do one last bilinear filter to mix those
together (see the three mixes in the return statement!). So basically,
bicubic filter is _5_ bilinear ops where 4 of those can be done in
fixed-function texture sampler hardware. The last one is done using a
shader.

I used this in OpenGL-accelerated image viewer for Mac OS X, Windows
and Linux, above filter is a plugin for the viewer (the plugins are
simple GLSL shaders with a header which configures the hardware state,
for example in this case we would want to use GL_LINEAR min/mag
filters so that we get the desired samples out).

I left the bicubic function as exercise to the reader, it's trivial
anyway. =)

albert_...@yahoo.fr

unread,
Dec 10, 2012, 8:27:25 AM12/10/12
to
Hi,

Could you share your code for the "cubic" function ?

I know this is "trivial anyway" but I tried to implement it with "triangular" function or other functions from here : http://www.codeproject.com/Articles/236394/Bi-Cubic-and-Bi-Linear-Interpolation-with-GLSL#GLSLBiCubic

And I didn't get correct images...

Thanks !
0 new messages