Acabo de implementar un muestreo de textura interpolado al muestrear los píxeles 4x4 más cercanos y luego hacer la interpolación de Lagrange en el eje x para obtener cuatro valores para usar la interpolación de Lagrange en el eje y.
¿Es esto lo mismo que la interpolación bicúbica o es diferente? ¿O hay diferentes tipos de interpolación bicúbica, y este es quizás uno de ellos?
Implementación de Webgl Shadertoy aquí y código GLSL (WebGL) relevante a continuación: https://www.shadertoy.com/view/MllSzX
¡Gracias!
float c_textureSize = 64.0;
float c_onePixel = 1.0 / c_textureSize;
float c_twoPixels = 2.0 / c_textureSize;
float c_x0 = -1.0;
float c_x1 = 0.0;
float c_x2 = 1.0;
float c_x3 = 2.0;
//=======================================================================================
vec3 CubicLagrange (vec3 A, vec3 B, vec3 C, vec3 D, float t)
{
return
A *
(
(t - c_x1) / (c_x0 - c_x1) *
(t - c_x2) / (c_x0 - c_x2) *
(t - c_x3) / (c_x0 - c_x3)
) +
B *
(
(t - c_x0) / (c_x1 - c_x0) *
(t - c_x2) / (c_x1 - c_x2) *
(t - c_x3) / (c_x1 - c_x3)
) +
C *
(
(t - c_x0) / (c_x2 - c_x0) *
(t - c_x1) / (c_x2 - c_x1) *
(t - c_x3) / (c_x2 - c_x3)
) +
D *
(
(t - c_x0) / (c_x3 - c_x0) *
(t - c_x1) / (c_x3 - c_x1) *
(t - c_x2) / (c_x3 - c_x2)
);
}
//=======================================================================================
vec3 BicubicTextureSample (vec2 P)
{
vec2 pixel = P * c_textureSize + 0.5;
vec2 frac = fract(pixel);
pixel = floor(pixel) / c_textureSize - vec2(c_onePixel/2.0);
vec3 C00 = texture2D(iChannel0, pixel + vec2(-c_onePixel ,-c_onePixel)).rgb;
vec3 C10 = texture2D(iChannel0, pixel + vec2( 0.0 ,-c_onePixel)).rgb;
vec3 C20 = texture2D(iChannel0, pixel + vec2( c_onePixel ,-c_onePixel)).rgb;
vec3 C30 = texture2D(iChannel0, pixel + vec2( c_twoPixels,-c_onePixel)).rgb;
vec3 C01 = texture2D(iChannel0, pixel + vec2(-c_onePixel , 0.0)).rgb;
vec3 C11 = texture2D(iChannel0, pixel + vec2( 0.0 , 0.0)).rgb;
vec3 C21 = texture2D(iChannel0, pixel + vec2( c_onePixel , 0.0)).rgb;
vec3 C31 = texture2D(iChannel0, pixel + vec2( c_twoPixels, 0.0)).rgb;
vec3 C02 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_onePixel)).rgb;
vec3 C12 = texture2D(iChannel0, pixel + vec2( 0.0 , c_onePixel)).rgb;
vec3 C22 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_onePixel)).rgb;
vec3 C32 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_onePixel)).rgb;
vec3 C03 = texture2D(iChannel0, pixel + vec2(-c_onePixel , c_twoPixels)).rgb;
vec3 C13 = texture2D(iChannel0, pixel + vec2( 0.0 , c_twoPixels)).rgb;
vec3 C23 = texture2D(iChannel0, pixel + vec2( c_onePixel , c_twoPixels)).rgb;
vec3 C33 = texture2D(iChannel0, pixel + vec2( c_twoPixels, c_twoPixels)).rgb;
vec3 CP0X = CubicLagrange(C00, C10, C20, C30, frac.x);
vec3 CP1X = CubicLagrange(C01, C11, C21, C31, frac.x);
vec3 CP2X = CubicLagrange(C02, C12, C22, C32, frac.x);
vec3 CP3X = CubicLagrange(C03, C13, C23, C33, frac.x);
return CubicLagrange(CP0X, CP1X, CP2X, CP3X, frac.y);
}