Tôi vừa thực hiện một số lấy mẫu kết cấu nội suy bằng cách lấy mẫu các pixel gần nhất 4 x 4 sau đó thực hiện phép nội suy Lagrange trên trục x để có bốn giá trị sử dụng phép nội suy Lagrange trên trục y.
Đây có phải giống như nội suy bicubic hay nó khác nhau? Hoặc có nhiều loại nội suy hai chiều khác nhau, và đây chỉ là một trong số chúng?
Triển khai Webgl Shadertoy tại đây và mã GLSL (WebGL) có liên quan bên dưới: https://www.shadertoy.com/view/MllSzX
Cảm ơn!
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);
}