diff --git a/crt/shaders/zfast_crt/zfast_crt_composite.slang b/crt/shaders/zfast_crt/zfast_crt_composite.slang index 6e59006..d753870 100644 --- a/crt/shaders/zfast_crt/zfast_crt_composite.slang +++ b/crt/shaders/zfast_crt/zfast_crt_composite.slang @@ -19,18 +19,21 @@ layout(push_constant) uniform Push vec4 OriginalSize; vec4 OutputSize; uint FrameCount; -float pi, blurx, blury, HIGHSCANAMOUNT1, HIGHSCANAMOUNT2, MASK_DARK, MASK_FADE, sat, FLICK; +float pi, blurx, blury, HIGHSCANAMOUNT1, HIGHSCANAMOUNT2, MASK_DARK, MASK_FADE, sat, FLICK,TYPE,Curvature; } params; -#pragma parameter blurx "Convergence X-Axis" 0.45 -1.0 2.0 0.05 -#pragma parameter blury "Convergence Y-Axis" -0.25 -1.0 1.0 0.05 +#pragma parameter Curvature "Curvature" 1.0 0.0 1.0 1.0 +#pragma parameter blurx "Convergence X-Axis" 0.85 -1.0 2.0 0.05 +#pragma parameter blury "Convergence Y-Axis" -0.10 -1.0 1.0 0.05 #pragma parameter HIGHSCANAMOUNT1 "Scanline Amount (Low)" 0.4 0.0 1.0 0.05 #pragma parameter HIGHSCANAMOUNT2 "Scanline Amount (High)" 0.3 0.0 1.0 0.05 +#pragma parameter TYPE "Mask Type" 0.0 0.0 1.0 1.0 #pragma parameter MASK_DARK "Mask Effect Amount" 0.3 0.0 1.0 0.05 #pragma parameter MASK_FADE "Mask/Scanline Fade" 0.7 0.0 1.0 0.05 #pragma parameter sat "Saturation" 1.0 0.0 3.0 0.05 #pragma parameter FLICK "Flicker" 10.0 0.0 50.0 1.0 + #define pi 3.14159 #define blurx params.blurx #define blury params.blury @@ -41,9 +44,13 @@ float pi, blurx, blury, HIGHSCANAMOUNT1, HIGHSCANAMOUNT2, MASK_DARK, MASK_FADE, #define MASK_FADE params.MASK_FADE #define sat params.sat #define FLICK params.FLICK +#define Curvature params.Curvature +#define TYPE params.TYPE + #define SourceSize params.SourceSize #define OriginalSize params.OriginalSize #define OutputSize params.OutputSize +#define scale vec4(SourceSize.xy/OriginalSize.xy,OriginalSize.xy/SourceSize.xy) layout(std140, set = 0, binding = 0) uniform UBO { @@ -55,18 +62,22 @@ layout(location = 0) in vec4 Position; layout(location = 1) in vec2 TexCoord; layout(location = 0) out vec2 vTexCoord; layout(location = 1) out float maskFade; +layout(location = 2) out float omega; void main() { gl_Position = global.MVP * Position; vTexCoord = TexCoord*1.0001; maskFade = 0.3333*MASK_FADE; + omega = 2.0*pi*SourceSize.y; } #pragma stage fragment layout(location = 0) in vec2 vTexCoord; layout(location = 1) in float maskFade; +layout(location = 2) in float omega; + layout(location = 0) out vec4 FragColor; layout(set = 0, binding = 2) uniform sampler2D Source; @@ -75,13 +86,36 @@ layout(set = 0, binding = 2) uniform sampler2D Source; #define iTimer (float(params.FrameCount)*2.0) #define flicker FLICK/1000.0 +// Distortion of scanlines, and end of screen alpha. +vec2 Warp(vec2 pos) +{ + pos = pos*2.0-1.0; + pos *= vec2(1.0 + (pos.y*pos.y)*0.03, 1.0 + (pos.x*pos.x)*0.05); + + return pos*0.5 + 0.5; +} + + void main() { - vec2 pos = vTexCoord; - float cent = floor(vTexCoord.y*SourceSize.y)+0.5; + vec2 pos,corn; + if (Curvature == 1.0) +{ + pos = Warp(vTexCoord.xy); + corn = min(pos,vec2(1.0)-pos); // This is used to mask the rounded + corn.x = 0.00001/corn.x; // corners later on + +} + + else pos = vTexCoord; + float OGL2Pos = pos.y*SourceSize.y; + float cent = floor(OGL2Pos)+0.5; float ycoord = cent*SourceSize.w; - pos = vec2(vTexCoord.x,ycoord); + ycoord = mix(pos.y,ycoord,0.6); + pos = vec2(pos.x,ycoord); + + vec3 sample1 = sin(iTimer)*flicker + texture(Source,vec2(pos.x + blur_x, pos.y - blur_y)).rgb; vec3 sample2 = 0.5*texture(Source,pos).rgb; vec3 sample3 = sin(iTimer)*flicker + texture(Source,vec2(pos.x - blur_x, pos.y + blur_y)).rgb; @@ -90,23 +124,33 @@ void main() sample1.g*0.25 + sample2.g + sample3.g*0.25, sample2.b + sample3.b*0.5); + vec3 interl = colour; vec3 lumweight=vec3(0.22,0.71,0.07); - float lum = dot(colour,lumweight); + float lumsat = dot(colour,lumweight); - vec3 graycolour = vec3(lum); + vec3 graycolour = vec3(lumsat); colour = vec3(mix(graycolour,colour.rgb,sat)); float SCANAMOUNT = mix(HIGHSCANAMOUNT1,HIGHSCANAMOUNT2,max(max(colour.r,colour.g),colour.b)); - - float scanLine = SCANAMOUNT * sin(fract(vTexCoord.y*SourceSize.y)*3.14159)+1.0-SCANAMOUNT; - - if (OriginalSize.y > 400.0) scanLine = 1.0; + - float whichmask = fract(vTexCoord.x*OutputSize.x*0.4999); - float mask = 1.0 + float(whichmask < 0.5) * -MASK_DARK; + if (OriginalSize.y > 400.0) { + colour ; + } +else { + colour *= SCANAMOUNT * sin(fract(OGL2Pos)*3.14159)+1.0-SCANAMOUNT; + colour *= SCANAMOUNT * sin(fract(1.0-OGL2Pos)*3.14159)+1.0-SCANAMOUNT; + colour *= SCANAMOUNT * sin(fract(1.0+OGL2Pos)*3.14159)+1.0-SCANAMOUNT; + } + + float steps; if (TYPE == 0.0) steps = 0.5; else steps = 0.3333; + float whichmask = fract(vTexCoord.x*OutputSize.x*steps); + float mask = 1.0 + float(whichmask < steps) * -MASK_DARK; + + colour.rgb = mix(mask*colour, colour, dot(colour.rgb,vec3(maskFade))); + + if (Curvature == 1.0 && corn.y < corn.x || Curvature == 1.0 && corn.x < 0.00001 ) + colour = vec3(0.0); - colour *= colour; - colour.rgb *= mix(mask*scanLine, scanLine, dot(colour.rgb,vec3(maskFade))); - colour = sqrt(colour); FragColor.rgb = colour.rgb; } diff --git a/interpolation/half_res.slangp b/interpolation/half_res.slangp new file mode 100644 index 0000000..097b454 --- /dev/null +++ b/interpolation/half_res.slangp @@ -0,0 +1,8 @@ +shaders = "1" +feedback_pass = "0" +shader0 = "../stock.slang" +filter_linear0 = false +scale_type_x0 = "source" +scale_x0 = "1.0" +scale_type_y0 = "source" +scale_y0 = "0.5" \ No newline at end of file diff --git a/ntsc/ntsc-feather.slangp b/ntsc/ntsc-feather.slangp new file mode 100644 index 0000000..285359e --- /dev/null +++ b/ntsc/ntsc-feather.slangp @@ -0,0 +1,6 @@ +shaders = 1 +shader0 = shaders/ntsc-simple/ntsc-feather.slang +filter_linear0 = true + + + diff --git a/ntsc/shaders/ntsc-simple/ntsc-feather.slang b/ntsc/shaders/ntsc-simple/ntsc-feather.slang new file mode 100644 index 0000000..f71b7f7 --- /dev/null +++ b/ntsc/shaders/ntsc-simple/ntsc-feather.slang @@ -0,0 +1,146 @@ +#version 450 + + +layout(push_constant) uniform Push +{ + float MASK; + float COMPOSITE_LOWPASS; + float COL_BLEED; + float NTSC_COL; + +} params; + + +#pragma parameter MASK "Color Subcarrier Artifacts" 0.08 0.0 1.0 0.01 +#pragma parameter COMPOSITE_LOWPASS "Composite Lowpass" 0.8 0.0 2.0 0.05 +#pragma parameter COL_BLEED "Chroma Bleed" 1.4 0.0 2.0 0.05 +#pragma parameter NTSC_COL "NTSC Colors " 0.0 0.0 1.0 1.0 + +#define MASK params.MASK +#define COMPOSITE_LOWPASS params.COMPOSITE_LOWPASS +#define COL_BLEED params.COL_BLEED +#define NTSC_COL params.NTSC_COL +#define PI 3.141592 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; + uint FrameCount; + +} global; + + +#define OutputSize global.OutputSize +#define SourceSize global.SourceSize +#define OriginalSize global.OriginalSize +#define FrameCount global.FrameCount + + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 vTexCoord; + +void main() +{ + gl_Position = global.MVP * Position; + vTexCoord = TexCoord * 1.0001; +} + + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + + + +mat3 RGBtoYIQ = mat3( + 0.2989, 0.5870, 0.1140, + 0.5959, -0.2744, -0.3216, + 0.2115, -0.5229, 0.3114); + +mat3 YIQtoRGB = mat3( + 1.0, 0.956, 0.6210, + 1.0, -0.2720, -0.6474, + 1.0, -1.1060, 1.7046); + +const mat3 NTSC = mat3( + 1.8088923, -0.6480268, -0.0833558, + 0.4062922 , 0.6175271, -0.0038849, + -0.0025872, -0.103848 , 1.182318); + +#define Time sin(float(FrameCount)) + +float phase = OriginalSize.x<300.0 ? 4.0*PI/15.0 : PI/3.0; +#define SC MASK*sin(vTexCoord.x*SourceSize.x*phase)+1.0-MASK + +void main() +{ + + vec2 cent = floor(vTexCoord*SourceSize.xy)+0.5; + vec2 coords = cent*SourceSize.zw; + coords = vec2(mix(vTexCoord.x,coords.x,0.2),coords.y); + + vec3 res = texture(Source,coords).rgb; res *= RGBtoYIQ; + float onetexel = SourceSize.z*COMPOSITE_LOWPASS; + float bleed = SourceSize.z*COL_BLEED; + vec3 resr = texture(Source,coords-(vec2(2.0*bleed,0.0))).rgb; resr *= RGBtoYIQ; + vec3 resru = texture(Source,coords-(vec2(onetexel,0.0))).rgb; resru *= RGBtoYIQ; + vec3 resrr = texture(Source,coords-(vec2(3.0*bleed,0.0))).rgb; resrr *= RGBtoYIQ; + + vec3 resl = texture(Source,coords+(vec2(2.0*bleed,0.0))).rgb; resl *= RGBtoYIQ; + vec3 reslu = texture(Source,coords+(vec2(bleed,0.0))).rgb; reslu *= RGBtoYIQ; + vec3 resll = texture(Source,coords+(vec2(3.0*bleed,0.0))).rgb; resll *= RGBtoYIQ; + + //color bleed + res.gb += (resr.gb+resl.gb+resrr.gb+resll.gb+reslu.gb+resru.gb); res.gb /= 7.0; + //overall bluriness + res.r = (res.r + resru.r)/2.0; + + vec3 checker = texture(Source,vTexCoord - vec2(0.25/OriginalSize.x,0.0)).rgb; checker *= RGBtoYIQ; + vec3 checkerl = texture(Source,vTexCoord + vec2(0.1/OriginalSize.x,0.0)).rgb; checkerl *= RGBtoYIQ; + + float diff = res.g-checker.g; + float diffl = res.g-checkerl.g; + float ydiff = res.r-checker.r; + float ydiffl = res.r-checkerl.r; + + float x = mod(floor(vTexCoord.x*SourceSize.x),2.0); + float y = mod(floor(vTexCoord.y*SourceSize.y),2.0); + + +//Color subcarrier pattern + if (y == 0.0 && x == 0.0 && Time < 0.0 && diff > 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && diff > 0.0) + + res.b *= SC; // ok + + else if (y == 1.0 && x == 1.0 && Time < 0.0 && diff > 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && diff > 0.0) + + res.b *= SC; // ok + + else if (y == 0.0 && x == 0.0 && Time < 0.0 && ydiff < 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && ydiff < 0.0) + + res.r *= SC; // ok + + else if (y == 1.0 && x == 1.0 && Time < 0.0 && ydiff < 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && ydiff < 0.0) + res.r *= SC; // ok + + else if (y == 0.0 && x == 0.0 && Time < 0.0 && ydiffl < 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && ydiffl < 0.0) + + res.r *= SC; + + else if (y == 1.0 && x == 1.0 && Time < 0.0 && ydiffl < 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && ydiffl < 0.0) + res.r *= SC; + +//for testing +//if (ydiffl < 0.0) res = vec3(0.0); + +/// + res *= YIQtoRGB; + if (NTSC_COL == 1.0)res *= NTSC; + FragColor = vec4(res,1.0); +}