Last active
October 13, 2020 00:07
-
-
Save butterw/8190fe5f9c24687ee96bb6f188b9222b to your computer and use it in GitHub Desktop.
compensated Lanczos3 pass X (from mpc-be, adapted for mpc-hc user shader)
This file contains hidden or 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
| // compensated Lanczos3, pass X | |
| // originally from mpc-be: https://sourceforge.net/p/mpcbe/code/HEAD/tree/trunk/src/Shaders/Resizers/resizer_lanczos3_x.hlsl | |
| // adapted for use in mpc-hc (as zoomX=2) by butterw (license: GPL v3) | |
| // use as a pre-resize shader, input resolution should match the screen resolution (no player resize involved) | |
| // pass X perf: (6 texture, 79 arithmetic) | |
| // A catmull-rom resizer (true separable kernel) is also available: resizer_catmull4_x.hlsl. Catmull-Rom spline4, pass X: (4 texture, 22 arithmetic) | |
| sampler s0: register(s0); | |
| float2 p0: register(c0); // W, H | |
| float2 p1: register(c1); //px, py | |
| #define PI 3.14159265 //acos(-1) | |
| float4 main(float2 tex: TEXCOORD0): COLOR { | |
| float coord = 0.5*tex.x*p0.x; // butterw: Any resize ratio is possible. coord = tex.x*p0.x/zoomX here with zoomX=2.; | |
| float t = frac(coord); | |
| coord = (coord-t + 0.5)*p1.x; | |
| // original pixels | |
| float4 Q2 = tex2D(s0, float2(coord, tex.y)); // nearest original pixel to the left | |
| // if (!t) return Q2; // float4(1, 0, 0, 1); butterw: no longer required | |
| // case t == 0. is required to return sample Q2, because of a possible division by 0. | |
| float4 Q0 = tex2D(s0, float2(coord -2*p1.x, tex.y)); | |
| float4 Q1 = tex2D(s0, float2(coord -p1.x, tex.y)); | |
| float4 Q3 = tex2D(s0, float2(coord +p1.x, tex.y)); | |
| float4 Q4 = tex2D(s0, float2(coord +2*p1.x, tex.y)); | |
| float4 Q5 = tex2D(s0, float2(coord +3*p1.x, tex.y)); | |
| // calculate weights | |
| float3 wset0 = t*PI + float3(2, 1, 0)*PI; | |
| float3 wset1 = -t*PI + float3(1, 2, 3)*PI; | |
| float3 wset0s = wset0*.5; | |
| float3 wset1s = wset1*.5; | |
| float3 w0 = sin(wset0) *sin(wset0s)/(wset0*wset0s); | |
| float3 w1 = sin(wset1) *sin(wset1s)/(wset1*wset1s); | |
| float wc = 1. -dot(1., w0+w1); // compensate truncated window factor by linear factoring on the two nearest samples | |
| w0.z+= wc*(1.-t); | |
| w1.x+= wc*t; | |
| return w0.x*Q0 + w0.y*Q1 + w0.z*Q2 + w1.x*Q3 + w1.y*Q4 + w1.z*Q5; // interpolation output | |
| } | |
| /* | |
| in mpc-be resizer was: | |
| // float t = frac(tex.x); | |
| // float2 pos = tex-float2(t, 0.); | |
| // float4 Q1 = tex2D(s0, (pos+float2(-.5, .5))*dxdy); | |
| The mpc-be resizer uses pixel scale for the tex.x coordinate. | |
| ex tex.x: 421.5 for a 1000x1000 output frame, whereas the typical hlsl scale, used in mpc-hc/be user shaders is [0, 1.] | |
| For 2x magnification, the corresponding input texel center would be at: 210.75 -0.75 +0.5=210.5 in output frame coordinates, given the half-pixel offset of texel centers in hlsl. | |
| butterw: Changed to: tex.x in [0, 1.0] for mpc-hc user shader | |
| float2 p0: register(c0); //W, H | |
| float2 p1: register(c1); //px, py | |
| ... | |
| float coord = 0.5*tex.x*p0.x; // butterw: for 2x Magnification (any float value possible). coord = 1./ZoomX*tex.x*p0.x; (tex.x - p1.x)*0.5*p0.x; | |
| float t = frac(coord); | |
| coord = (coord-t + 0.5)*p1.x; //texel centers are at half pixel offset in hlsl. | |
| >> float4 Q1 = tex2D(s0, float2(coord - p1.x, tex.y)); | |
| could use a getX(x_poffset) function, but it has the same perf: | |
| #define getX(x_poffset) float4 tex2D(s0, float2(coord+x_poffset*p1.x, tex.y)) | |
| >> float4 Q1 = getX(-1); | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment