Saya baru saja menerapkan beberapa sampling tekstur interpolasi dengan mengambil sampel piksel terdekat 4x4 kemudian melakukan interpolasi Lagrange melintasi sumbu x untuk mendapatkan empat nilai untuk menggunakan interpolasi Lagrange pada melintasi sumbu y.
Apakah ini sama dengan interpolasi bikubik atau berbeda? Atau ada berbagai macam interpolasi bikubik, dan ini mungkin salah satunya saja?
Implementasi Webgl Shadertoy di sini dan kode GLSL (WebGL) yang relevan di bawah: https://www.shadertoy.com/view/MllSzX
Terima kasih!
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
sumber
sumber
Jawaban:
Ternyata tidak, sementara Anda dapat menggunakan interpolasi Lagrange bikubik untuk pengambilan sampel tekstur bikubik, itu bukan pilihan kualitas tertinggi, dan mungkin sebenarnya tidak mungkin digunakan.
Cubic hermite splines adalah alat yang lebih baik untuk pekerjaan itu.
Interpolasi Lagrange akan membuat kurva yang melewati titik-titik data, sehingga menjaga kontinuitas C0, tetapi hermite splines mempertahankan turunannya di tepian sementara juga melewati titik-titik data, sehingga menjaga kontinuitas C1 dan terlihat jauh lebih baik.
Pertanyaan ini memiliki beberapa info hebat tentang splines hermite kubik: /signals/18265/bicubic-interpolation
Ini adalah versi hermite kubik dari kode yang saya posting di pertanyaan:
Berikut adalah gambar yang menunjukkan perbedaan antara metode pengambilan sampel. Dari kiri ke kanan: Tetangga Terdekat, Bilinear, Lagrange Bicubic, Hermite Bicubic
sumber