diff --git a/src/video_core/host_shaders/present_lanczos.frag b/src/video_core/host_shaders/present_lanczos.frag index 9501b7ca33..b69b329c1b 100644 --- a/src/video_core/host_shaders/present_lanczos.frag +++ b/src/video_core/host_shaders/present_lanczos.frag @@ -9,23 +9,29 @@ layout (location = 0) in vec2 frag_tex_coord; layout (location = 0) out vec4 color; layout (binding = 0) uniform sampler2D color_texture; -// precomputed kernel -const float w_kernel[49] = float[] ( - -0.238811f, 0.531959f, 0.961865f, 1.000000f, 0.961865f, 0.531959f, -0.238811f, 0.531959f, 0.957419f, 0.313883f, -0.000000f, 0.313883f, 0.957419f, 0.531959f, 0.961865f, 0.313883f, -0.322602f, 0.000000f, -0.322602f, 0.313883f, 0.961865f, 1.000000f, -0.000000f, 0.000000f, 1.000000f, 0.000000f, -0.000000f, 1.000000f, 0.961865f, 0.313883f, -0.322602f, 0.000000f, -0.322602f, 0.313883f, 0.961865f, 0.531959f, 0.957419f, 0.313883f, -0.000000f, 0.313883f, 0.957419f, 0.531959f, -0.238811f, 0.531959f, 0.961865f, 1.000000f, 0.961865f, 0.531959f, -0.238811f -); -const vec2 w_pos[49] = vec2[] ( - vec2(-0.750000f, -0.750000f), vec2(-0.750000f, -0.500000f), vec2(-0.750000f, -0.250000f), vec2(-0.750000f, 0.000000f), vec2(-0.750000f, 0.250000f), vec2(-0.750000f, 0.500000f), vec2(-0.750000f, 0.750000f), vec2(-0.500000f, -0.750000f), vec2(-0.500000f, -0.500000f), vec2(-0.500000f, -0.250000f), vec2(-0.500000f, 0.000000f), vec2(-0.500000f, 0.250000f), vec2(-0.500000f, 0.500000f), vec2(-0.500000f, 0.750000f), vec2(-0.250000f, -0.750000f), vec2(-0.250000f, -0.500000f), vec2(-0.250000f, -0.250000f), vec2(-0.250000f, 0.000000f), vec2(-0.250000f, 0.250000f), vec2(-0.250000f, 0.500000f), vec2(-0.250000f, 0.750000f), vec2(0.000000f, -0.750000f), vec2(0.000000f, -0.500000f), vec2(0.000000f, -0.250000f), vec2(0.000000f, 0.000000f), vec2(0.000000f, 0.250000f), vec2(0.000000f, 0.500000f), vec2(0.000000f, 0.750000f), vec2(0.250000f, -0.750000f), vec2(0.250000f, -0.500000f), vec2(0.250000f, -0.250000f), vec2(0.250000f, 0.000000f), vec2(0.250000f, 0.250000f), vec2(0.250000f, 0.500000f), vec2(0.250000f, 0.750000f), vec2(0.500000f, -0.750000f), vec2(0.500000f, -0.500000f), vec2(0.500000f, -0.250000f), vec2(0.500000f, 0.000000f), vec2(0.500000f, 0.250000f), vec2(0.500000f, 0.500000f), vec2(0.500000f, 0.750000f), vec2(0.750000f, -0.750000f), vec2(0.750000f, -0.500000f), vec2(0.750000f, -0.250000f), vec2(0.750000f, 0.000000f), vec2(0.750000f, 0.250000f), vec2(0.750000f, 0.500000f), vec2(0.750000f, 0.750000f) -); -const float w_sum = 21.045683f; +#define PI 3.1415926535897932384626433 +float sinc(float x) { + return x == 0.0f ? 1.0f : sin(PI * x) / (PI * x); +} +float lanczos(vec2 v, float a) { + float d = length(v); + return sinc(d) / sinc(d / a); +} vec4 textureLanczos(sampler2D textureSampler, vec2 p) { vec3 c_sum = vec3(0.0f); + float w_sum = 0.0f; vec2 res = vec2(textureSize(textureSampler, 0)); vec2 cc = floor(p * res) / res; - for (int i = 0; i < 49; i++) { // kernel size = (r * 2 + 1) ^ 2 - vec2 kp = w_pos[i] / res; - vec2 uv = cc + kp; - c_sum += w_kernel[i] * texture(textureSampler, p + kp).rgb; - } + // kernel size = (2r + 1)^2 + const int r = 3; //radius (1 = 3 steps) + for (int x = -r; x <= r; x++) + for (int y = -r; y <= r; y++) { + vec2 kp = 0.5f * (vec2(x, y) / res); // 0.5 = half-pixel level resampling + vec2 uv = cc + kp; + float w = lanczos(kp, float(r)); + c_sum += w * texture(textureSampler, p + kp).rgb; + w_sum += w; + } return vec4(c_sum / w_sum, 1.0f); }