Je viens d'implémenter un échantillonnage de texture interpolé en échantillonnant les 4x4 pixels les plus proches, puis en effectuant une interpolation Lagrange sur l'axe x pour obtenir quatre valeurs pour utiliser l'interpolation Lagrange sur l'axe y.
Est-ce la même chose que l'interpolation bicubique ou est-ce différent? Ou existe-t-il différents types d'interpolation bicubique, et ce n'est peut-être que l'un d'entre eux?
Implémentation de Webgl Shadertoy ici et code GLSL (WebGL) ci-dessous: https://www.shadertoy.com/view/MllSzX
Merci!
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);
}
texture
interpolation
Alan Wolfe
la source
la source
Réponses:
Il s'avère que non, bien que vous puissiez utiliser l'interpolation bicubique de Lagrange pour l'échantillonnage de texture bicubique, ce n'est pas l'option de la plus haute qualité, et probablement peu susceptible d'être utilisée.
Les cannelures hermite cubiques sont un meilleur outil pour le travail.
L'interpolation de Lagrange fera une courbe qui passe à travers les points de données, préservant ainsi la continuité C0, mais les splines hermites préservent les dérivées sur les bords tout en passant par les points de données, préservant ainsi la continuité C1 et semblant beaucoup mieux.
Cette question contient d'excellentes informations sur les splines cubiques d'hermite: /signals/18265/bicubic-interpolation
Voici la version hermite cubique du code que j'ai posté dans la question:
Voici une image montrant la différence entre les méthodes d'échantillonnage. De gauche à droite: le plus proche voisin, bilinéaire, Lagrange Bicubic, Hermite Bicubic
la source