Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Requires linear-downscaling=no.
// 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 HOOKED
//!BIND PREKERNEL
//!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 HOOKED
//!BIND L2
//!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.), int(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);
}
Copy link

ghost commented Feb 6, 2021

Why is it better to set linear-downscaling to no here? Can this shader be rewritten to support linear downscaling and would it have any advantage?

@igv
Copy link
Author

igv commented Feb 6, 2021

Less ringing artifacts. linear-downscaling should be used only with soft scalers (and only when it doesn't cause more aliasing artifacts).
But you can use it with linear-downscaling if you like it and don't notice any artifacts.

Copy link

ghost commented Feb 6, 2021

Ok, thanks for the answer

Copy link

ghost commented Feb 11, 2021

And another question, is it possible to turn sharpening completely off or just minimize it?

@igv
Copy link
Author

igv commented Feb 11, 2021

is it possible to turn sharpening completely off

This shader is a sharpener.

or just minimize it?

In the description.

Copy link

ghost commented Feb 11, 2021

Ok, thank you. Asked in case there could be some special values, like if 0 did nothing, for example

@crazysword1
Copy link

crazysword1 commented Apr 28, 2021

How do I access the new 16-04-1 (thanks for updating that).
You mentioned that it is in the archive but I can't find it anywhere on the page.
Thanks

@deus0ww
Copy link

deus0ww commented Apr 28, 2021

It's in checkpoints_params.7z.

@crazysword1
Copy link

crazysword1 commented Apr 28, 2021

thanks :)

@yeezylife
Copy link

yeezylife commented Oct 13, 2021

Noticed that you've updated several shaders these days.Cool!

Can be used with sharp scalers now (finally able to suppress ringing artifacts).

Any chance to tell us what's the recomonded dscale algos now(to use with SSimDownscaler)... spline36,lanczos,ewa_lanczossharp?

@igv
Copy link
Author

igv commented Oct 13, 2021

As always - catmull_rom or mitchell.

@yeezylife
Copy link

yeezylife commented Oct 13, 2021

Thanks for replying,I misunderstood the level of sharpness...

@igv
Copy link
Author

igv commented Oct 13, 2021

lanczos is a good choice too - less aliased than catmull_rom / mitchell.

@yeezylife
Copy link

yeezylife commented Oct 13, 2021

Can I use spline36 with SSimDownscaler now(Since "lanczos is a good choice too")?I thought it has less ringing than lanczos,and less aliasing than catmull_rom / mitchell(but sharper).

@igv
Copy link
Author

igv commented Oct 13, 2021

Sure.

Copy link

ghost commented Oct 25, 2021

My downscaling factor is <2x, should I use SSIMDownscaler or just something like lanczos or catrom? Which gives the "best" results?

@igv
Copy link
Author

igv commented Oct 25, 2021

lanczos with linear-downscaling=no

Copy link

ghost commented Oct 25, 2021

Thanks

Copy link

ghost commented Oct 25, 2021

By the way if I may ask, what is the reason you chose lancos over mitchell, catrom and other sane dscale algos? Is it because it produces the most perceived sharpness and is the least aliased of the three? If so, what about artifacts?

@yeezylife
Copy link

yeezylife commented Oct 25, 2021

I guess when your downscaling factor is <2x , the ringing artifacts that lanczos might cause wasn't that visible without zoom in.

@igv
Copy link
Author

igv commented Oct 25, 2021

Is it because it produces the most perceived sharpness and is the least aliased of the three?

Yes.

what about artifacts?

Ringing artifacts not perceivable with gamma light. And, after the latest update, SSimDownscaler blurs them instead of over-sharpening.

Copy link

ghost commented Oct 25, 2021

I see, thanks for answering. It has been very informative.

@cybergade
Copy link

cybergade commented Nov 29, 2021

Made an account to ask this guestion. This is probably unrelated to SSIMDownscaler but the comments above got me asking, when using catmull_rom only (yes, without ssimdownscaler), is it adviseable to use with linear-downscaling=yes?

@igv
Copy link
Author

igv commented Nov 29, 2021

It is advisable to use linear-downscaling=yes only with soft scalers (it was in comments above), and catmull_rom isn't a soft scaler.

@cybergade
Copy link

cybergade commented Nov 29, 2021

Ah, i was under the impression that catmull_rom was a softscaler. Thanks for clearing it up.

@yeezylife
Copy link

yeezylife commented Nov 30, 2021

Been testing vo=gpu-next gpu-api=vlukan lately and I accidentlly found out that SSimDownscaler results are very different than it's on vo=gpu gpu-api=d3d11
The dark line in the anime become thicker(also blurer) and you can see "gliches" around the edge

@igv
Copy link
Author

igv commented Nov 30, 2021

Can't reproduce.

@RafeeDaBoy
Copy link

RafeeDaBoy commented Jan 25, 2022

Hi, @igv You had mentioned here that "lanczos with linear-downscaling=no" would give a sharper result.

But you also mentioned here that this is tuned for mitchell.

When downscaling from 3840x2160 to 2560x1440, which one would yield better results?

@igv
Copy link
Author

igv commented Jan 25, 2022

lanczos

@RafeeDaBoy
Copy link

RafeeDaBoy commented Jan 25, 2022

Thank you for your response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment