Last active
October 23, 2024 13:39
-
-
Save igv/36508af3ffc84410fe39761d6969be10 to your computer and use it in GitHub Desktop.
Tuned for linear-downscaling=no.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This library is free software; you can redistribute it and/or | |
// modify it under the terms of the GNU Lesser General Public | |
// License as published by the Free Software Foundation; either | |
// version 3.0 of the License, or (at your option) any later version. | |
// | |
// This library is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
// Lesser General Public License for more details. | |
// | |
// You should have received a copy of the GNU Lesser General Public | |
// License along with this library. | |
//!HOOK POSTKERNEL | |
//!BIND PREKERNEL | |
//!BIND HOOKED | |
//!SAVE L2 | |
//!WIDTH NATIVE_CROPPED.w | |
//!WHEN NATIVE_CROPPED.h POSTKERNEL.h > | |
//!COMPONENTS 3 | |
//!DESC SSimDownscaler L2 pass 1 | |
#define axis 1 | |
#define offset vec2(0,0) | |
#define MN(B,C,x) (x < 1.0 ? ((2.-1.5*B-(C))*x + (-3.+2.*B+C))*x*x + (1.-(B)/3.) : (((-(B)/6.-(C))*x + (B+5.*C))*x + (-2.*B-8.*C))*x+((4./3.)*B+4.*C)) | |
#define Kernel(x) MN(.0, .5, abs(x)) | |
#define taps 2.0 | |
vec4 hook() { | |
vec2 base = PREKERNEL_pt * (PREKERNEL_pos * input_size + tex_offset); | |
float low = ceil((PREKERNEL_pos - taps*POSTKERNEL_pt) * input_size - offset + tex_offset - 0.5)[axis]; | |
float high = floor((PREKERNEL_pos + taps*POSTKERNEL_pt) * input_size - offset + tex_offset - 0.5)[axis]; | |
float W = 0.0; | |
vec4 avg = vec4(0); | |
vec2 pos = base; | |
for (float k = low; k <= high; k++) { | |
pos[axis] = PREKERNEL_pt[axis] * (k - offset[axis] + 0.5); | |
float rel = (pos[axis] - base[axis])*POSTKERNEL_size[axis]; | |
float w = Kernel(rel); | |
vec4 tex = textureLod(PREKERNEL_raw, pos, 0.0) * PREKERNEL_mul; | |
avg += w * tex * tex; | |
W += w; | |
} | |
avg /= W; | |
return avg; | |
} | |
//!HOOK POSTKERNEL | |
//!BIND L2 | |
//!BIND HOOKED | |
//!SAVE L2 | |
//!WHEN NATIVE_CROPPED.w POSTKERNEL.w > | |
//!COMPONENTS 3 | |
//!DESC SSimDownscaler L2 pass 2 | |
#define axis 0 | |
#define offset vec2(0,0) | |
#define MN(B,C,x) (x < 1.0 ? ((2.-1.5*B-(C))*x + (-3.+2.*B+C))*x*x + (1.-(B)/3.) : (((-(B)/6.-(C))*x + (B+5.*C))*x + (-2.*B-8.*C))*x+((4./3.)*B+4.*C)) | |
#define Kernel(x) MN(.0, .5, abs(x)) | |
#define taps 2.0 | |
vec4 hook() { | |
float low = ceil((L2_pos - taps*POSTKERNEL_pt) * L2_size - offset - 0.5)[axis]; | |
float high = floor((L2_pos + taps*POSTKERNEL_pt) * L2_size - offset - 0.5)[axis]; | |
float W = 0.0; | |
vec4 avg = vec4(0); | |
vec2 pos = L2_pos; | |
for (float k = low; k <= high; k++) { | |
pos[axis] = L2_pt[axis] * (k - offset[axis] + 0.5); | |
float rel = (pos[axis] - L2_pos[axis])*POSTKERNEL_size[axis]; | |
float w = Kernel(rel); | |
avg += w * textureLod(L2_raw, pos, 0.0) * L2_mul; | |
W += w; | |
} | |
avg /= W; | |
return avg; | |
} | |
//!HOOK POSTKERNEL | |
//!BIND HOOKED | |
//!BIND L2 | |
//!SAVE MR | |
//!WHEN NATIVE_CROPPED.h POSTKERNEL.h > | |
//!COMPONENTS 4 | |
//!DESC SSimDownscaler mean & R | |
#define oversharp 0.0 | |
#define sigma_nsq 10. / (255.*255.) | |
#define locality 2.0 | |
#define offset vec2(0,0) | |
#define Kernel(x) pow(1.0 / locality, abs(x)) | |
#define taps 3.0 | |
#define Luma(rgb) ( dot(rgb, vec3(0.2126, 0.7152, 0.0722)) ) | |
mat3x3 ScaleH(vec2 pos) { | |
float low = ceil(-0.5*taps - offset)[0]; | |
float high = floor(0.5*taps - offset)[0]; | |
float W = 0.0; | |
mat3x3 avg = mat3x3(0); | |
for (float k = low; k <= high; k++) { | |
pos[0] = HOOKED_pos[0] + HOOKED_pt[0] * k; | |
float rel = k + offset[0]; | |
float w = Kernel(rel); | |
vec3 L = POSTKERNEL_tex(pos).rgb; | |
avg += w * mat3x3(L, L*L, L2_tex(pos).rgb); | |
W += w; | |
} | |
avg /= W; | |
return avg; | |
} | |
vec4 hook() { | |
vec2 pos = HOOKED_pos; | |
float low = ceil(-0.5*taps - offset)[1]; | |
float high = floor(0.5*taps - offset)[1]; | |
float W = 0.0; | |
mat3x3 avg = mat3x3(0); | |
for (float k = low; k <= high; k++) { | |
pos[1] = HOOKED_pos[1] + HOOKED_pt[1] * k; | |
float rel = k + offset[1]; | |
float w = Kernel(rel); | |
avg += w * ScaleH(pos); | |
W += w; | |
} | |
avg /= W; | |
float Sl = Luma(max(avg[1] - avg[0] * avg[0], 0.)); | |
float Sh = Luma(max(avg[2] - avg[0] * avg[0], 0.)); | |
return vec4(avg[0], mix(sqrt((Sh + sigma_nsq) / (Sl + sigma_nsq)) * (1. + oversharp), clamp(Sh / Sl, 0., 1.), float(Sl > Sh))); | |
} | |
//!HOOK POSTKERNEL | |
//!BIND HOOKED | |
//!BIND MR | |
//!WHEN NATIVE_CROPPED.h POSTKERNEL.h > | |
//!DESC SSimDownscaler final pass | |
#define locality 2.0 | |
#define offset vec2(0,0) | |
#define Kernel(x) pow(1.0 / locality, abs(x)) | |
#define taps 3.0 | |
#define Gamma(x) ( pow(x, vec3(1.0/2.0)) ) | |
#define GammaInv(x) ( pow(clamp(x, 0.0, 1.0), vec3(2.0)) ) | |
mat3x3 ScaleH(vec2 pos) { | |
float low = ceil(-0.5*taps - offset)[0]; | |
float high = floor(0.5*taps - offset)[0]; | |
float W = 0.0; | |
mat3x3 avg = mat3x3(0); | |
for (float k = low; k <= high; k++) { | |
pos[0] = HOOKED_pos[0] + HOOKED_pt[0] * k; | |
float rel = k + offset[0]; | |
float w = Kernel(rel); | |
vec4 MR = MR_tex(pos); | |
avg += w * mat3x3(MR.a*MR.rgb, MR.rgb, MR.aaa); | |
W += w; | |
} | |
avg /= W; | |
return avg; | |
} | |
vec4 hook() { | |
vec2 pos = HOOKED_pos; | |
float low = ceil(-0.5*taps - offset)[1]; | |
float high = floor(0.5*taps - offset)[1]; | |
float W = 0.0; | |
mat3x3 avg = mat3x3(0); | |
for (float k = low; k <= high; k++) { | |
pos[1] = HOOKED_pos[1] + HOOKED_pt[1] * k; | |
float rel = k + offset[1]; | |
float w = Kernel(rel); | |
avg += w * ScaleH(pos); | |
W += w; | |
} | |
avg /= W; | |
vec4 L = POSTKERNEL_texOff(0); | |
return vec4(avg[1] + avg[2] * L.rgb - avg[0], L.a); | |
} |
No idea what is going on. Only happens when no upscaling or downscaling, but it clearly shouldn't. Ask mpv devs.
I'm running mpv via the render API (vo=libmpv) in an OpenGL ES 3.2 context, and getting the following error with this shader:
[ 2.754][e][libmpv_render] 0:118(22): error: no matching function for call to `mix(float, float, int)'; candidates are:
[ 2.754][e][libmpv_render] 0:118(22): error: float mix(float, float, float)
[ 2.754][e][libmpv_render] 0:118(22): error: vec2 mix(vec2, vec2, float)
...
The following patch gets the shader compiling, and appears to work fine, however I'm no GLSL expert. Are there any downsides to this change? Does it change the shader output/perform worse/etc.? I'm assuming there's a reason int
was used over float
, but maybe not.
From d048e7c2f052731cbdb0f175e90db01255702729 Mon Sep 17 00:00:00 2001
From: Ian Hattendorf <ian@ianhattendorf.com>
Date: Wed, 4 Sep 2024 10:19:56 -0700
Subject: [PATCH] mix(float, float, int) -> mix(float, float, float) for GLSL
ES support
---
SSimDownscaler.glsl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SSimDownscaler.glsl b/SSimDownscaler.glsl
index e2ec778..e969b6a 100644
--- a/SSimDownscaler.glsl
+++ b/SSimDownscaler.glsl
@@ -151,7 +151,7 @@ vec4 hook() {
float Sl = Luma(max(avg[1] - avg[0] * avg[0], 0.));
float Sh = Luma(max(avg[2] - avg[0] * avg[0], 0.));
- return vec4(avg[0], mix(sqrt((Sh + sigma_nsq) / (Sl + sigma_nsq)) * (1. + oversharp), clamp(Sh / Sl, 0., 1.), int(Sl > Sh)));
+ return vec4(avg[0], mix(sqrt((Sh + sigma_nsq) / (Sl + sigma_nsq)) * (1. + oversharp), clamp(Sh / Sl, 0., 1.), float(Sl > Sh)));
}
//!HOOK POSTKERNEL
--
2.46.0
KrigBilateral and SSimSuperRes are working perfectly with OpenGL ES.
Ref:
https://registry.khronos.org/OpenGL-Refpages/es3.0/html/mix.xhtml
https://registry.khronos.org/OpenGL-Refpages/gl4/html/mix.xhtml
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes I have
linear-downscaling≠no
I truly think its not worth turning on linear downscaling and the ringing it results in even with EWA scalers. I will have to test more when I have time bc. right now SSimD gets worst score on any IQA test, and it should be way higher in those tests.