From 1ea4c2f33d60bb8dd1f1caafd80659277a04d1c3 Mon Sep 17 00:00:00 2001 From: hunterk Date: Fri, 19 Jun 2020 16:19:28 -0500 Subject: [PATCH] add VHSPro ported from reshade --- vhs/VHSPro.slangp | 38 +++ vhs/shaders/VHSPro/VHSPro_Clear.slang | 37 +++ vhs/shaders/VHSPro/VHSPro_First.slang | 282 +++++++++++++++++ vhs/shaders/VHSPro/VHSPro_Forth.slang | 56 ++++ vhs/shaders/VHSPro/VHSPro_LastFrame.slang | 49 +++ vhs/shaders/VHSPro/VHSPro_Second.slang | 152 +++++++++ vhs/shaders/VHSPro/VHSPro_Tape.slang | 68 ++++ vhs/shaders/VHSPro/VHSPro_Third.slang | 66 ++++ vhs/shaders/VHSPro/VHSPro_constants.inc | 21 ++ vhs/shaders/VHSPro/VHSPro_functions.inc | 361 ++++++++++++++++++++++ vhs/shaders/VHSPro/VHSPro_params.inc | 246 +++++++++++++++ vhs/shaders/VHSPro/feedback.slang | 42 +++ vhs/shaders/VHSPro/taps.inc | 318 +++++++++++++++++++ 13 files changed, 1736 insertions(+) create mode 100644 vhs/VHSPro.slangp create mode 100644 vhs/shaders/VHSPro/VHSPro_Clear.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_First.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_Forth.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_LastFrame.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_Second.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_Tape.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_Third.slang create mode 100644 vhs/shaders/VHSPro/VHSPro_constants.inc create mode 100644 vhs/shaders/VHSPro/VHSPro_functions.inc create mode 100644 vhs/shaders/VHSPro/VHSPro_params.inc create mode 100644 vhs/shaders/VHSPro/feedback.slang create mode 100644 vhs/shaders/VHSPro/taps.inc diff --git a/vhs/VHSPro.slangp b/vhs/VHSPro.slangp new file mode 100644 index 0000000..571ea7d --- /dev/null +++ b/vhs/VHSPro.slangp @@ -0,0 +1,38 @@ +shaders = 6 + +#moved this to the first pass to avoid complications with feedback +shader0 = shaders/VHSPro/VHSPro_Third.slang +alias0 = third +scale_type0 = source +filter_linear0 = true + +shader1 = shaders/VHSPro/VHSPro_Tape.slang +alias1 = tape +filter_linear1 = true +scale_type1 = source + +shader2 = shaders/VHSPro/VHSPro_First.slang +alias2 = first +filter_linear2 = true +scale_type2 = source + +shader3 = shaders/VHSPro/VHSPro_Second.slang +alias3 = second +filter_linear3 = true +scale_type3 = source + +#doesn't really do anything for us +#shader4 = shaders/VHSPro/VHSPro_LastFrame.slang +#alias4 = lastframe +#filter_linear4 = true +#scale_type4 = source + +shader4 = shaders/VHSPro/VHSPro_Forth.slang +alias4 = forth +filter_linear4 = true +scale_type4 = source + +shader5 = shaders/VHSPro/VHSPro_Clear.slang +alias5 = clear +filter_linear5 = true +scale_type5 = source \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_Clear.slang b/vhs/shaders/VHSPro/VHSPro_Clear.slang new file mode 100644 index 0000000..6106b47 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_Clear.slang @@ -0,0 +1,37 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#define SamplerColorVHS Source + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 txcoord; + +void main() +{ + gl_Position = global.MVP * Position; + txcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 txcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#include "VHSPro_functions.inc" + +void main() +{ + FragColor = vec4(texture(SamplerColorVHS, txcoord).rgb, 1.0); +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_First.slang b/vhs/shaders/VHSPro/VHSPro_First.slang new file mode 100644 index 0000000..07d1c25 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_First.slang @@ -0,0 +1,282 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + int FrameDirection; +} params; + +#define SamplerColorVHS Original + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 txcoord; + +void main() +{ + gl_Position = global.MVP * Position; + txcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 txcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Original; +layout(set = 0, binding = 3) uniform sampler2D tape; + +#include "VHSPro_functions.inc" +#define SamplerTape tape + +void main() +{ + const float t = float(params.FrameCount) * 0.0075;//_Time.y; + vec2 p = txcoord.xy; + + float SLN = screenLinesNum; //TODO use only SLN + float SLN_Noise = noiseLinesNum; //TODO only SLN_Noise + float ONE_X = 0.0; + float ONE_Y = 0.0; + + //basically if its 0 -> set it to fullscreen + //TODO calc it before shader / already float done + SLN = screenLinesNum; //TODO use only SLN + SLN_Noise = noiseLinesNum; //TODO only SLN_Noise + if(SLN==0.0) SLN = _ScreenParams.y; + + if(SLN_Noise==0 || SLN_Noise>SLN) SLN_Noise = SLN; + + ONE_X = 1.0/_ScreenParams.x; //assigning works only here + ONE_Y = 1.0/_ScreenParams.y; + + + if (VHS_Twitch_V){ + p = twitchVertical(0.5*twitchVFreq, p, t); + } + + if (VHS_Twitch_H){ + p = twitchHorizonal(0.1*twitchHFreq, p, t); + } + + //make discrete lines /w or wo float + if(VHS_LinesFloat){ + float sh = fract(-t*linesFloatSpeed); //shift // float sh = fmod(t, 1.); //shift + // if(p.x>0.5) + p.y = -floor( -p.y * SLN + sh )/SLN + sh/SLN; //v1.3 + // p.y = floor( p.y * SLN + sh )/SLN - sh/SLN; //v1.2 + } else { + // if(p.x>0.5) + p.y = -floor( -p.y * SLN )/SLN; //v1.3 + // p.y = floor( p.y * SLN )/SLN; //v1.2 + } + + if (VHS_Stretch){ + p = stretch(p, t, 15.0, 1.0, 0.5, 0.0); + p = stretch(p, t, 8.0, 1.2, 0.45, 0.5); + p = stretch(p, t, 11.0, 0.5, -0.35, 0.25); //up + } + + if (VHS_Jitter_H){ + if( fmod( p.y * SLN, 2.0)<1.0) + p.x += ONE_X*sin(t*130.0)*jitterHAmount; + } + + //just init + vec3 col = vec3(0.0,0.0,0.0); + vec3 signal = vec3(0.0,0.0,0.0);// rgb2yiq(col); + + //gotta initiate all these things here coz of tape noise distortion + + //[NOISE uv init] + //if SLN_Noise different from SLN->recalc linefloat + vec2 pn = p; + if(SLN!=SLN_Noise){ + if(VHS_LineNoise){ + const float sh = fract(t); //shift // float sh = fmod(t, 1.); //shift + pn.y = floor( pn.y * SLN_Noise + sh )/SLN_Noise - sh/SLN_Noise; + } else { + pn.y = floor( pn.y * SLN_Noise )/SLN_Noise; + } + } + + //SLN_X is quantization of X. goest from _ScreenParams.x to SLN_X + const float ScreenLinesNumX = SLN_Noise * _ScreenParams.x / _ScreenParams.y; + const float SLN_X = noiseQuantizeX*(_ScreenParams.x - ScreenLinesNumX) + ScreenLinesNumX; + pn.x = floor( pn.x * SLN_X )/SLN_X; + + const vec2 pn_ = pn*_ScreenParams.xy; + + //TODO probably it shud be 1.0/SLN_Noise + const float ONEXN = 1.0/SLN_X; + //[//noise uv init] + + float distShift = 0; // for 2nd part of tape noise + + if (VHS_TapeNoise) { + + //uv distortion part of tapenoise + distShift = 0; // for 2nd part of tape noise + for (int ii = 0; ii < 20 % 1023; ii++){ + + //this is t.n. line value at pn.y and down each pixel + //TODO i guess ONEXN shud be 1.0/sln noise + float tnl = textureLod(SamplerTape, vec2(0.0,pn.y-ONEXN*ii), 0.).y; + // float tnl = texture(SamplerTape, vec2(0.0,pn.y-ONEXN*ii)).y; + // float tnl = tapeNoiseLines(vec2(0.0,pn.y-ONEXN*i), t*tapeNoiseSpeed)*tapeNoiseAmount; + tnl -= 0.15 * float(params.FrameDirection); + // float fadediff = hash12(vec2(pn.x-ONEXN*i,pn.y)); + if(tnl>0.27) { + //TODO get integer part other way + const float sh = sin( 1.0*PI*(float(ii)/float(20))) ; //0..1 + p.x -= float(int(sh)*4.0*ONEXN); //displacement + distShift += sh ; //for 2nd part + // p.x += ONEXN * float(int(((tnl-thth)/thth)*4.0)); + // col.x = sh; + } + } + } + + //uv transforms over + + //picture proccess start + if (VHS_Jitter_V){ + signal = yiqDist(p, jitterVAmount, t*jitterVSpeed); + } else { + col = texture(SamplerColorVHS, p).rgb; + // col = vec3(p.xy, 0.0);//debug + signal = rgb2yiq(col); + } + + + if (VHS_LineNoise || VHS_FilmGrain){ + signal.x += texture(SamplerTape, pn).z; + } + + //iq noise from yiq + if (VHS_YIQNoise){ + if (signalNoiseType == 0) { + //TODO make cheaper noise + //type 1 (best) w Y mask + const vec2 noise = n4rand_bw( pn_,t,1.0-signalNoisePower ) ; + signal.y += (noise.x*2.0-1.0)*signalNoiseAmount*signal.x; + signal.z += (noise.y*2.0-1.0)*signalNoiseAmount*signal.x; + } else if (signalNoiseType == 1){ + //type 2 + const vec2 noise = n4rand_bw( pn_,t, 1.0-signalNoisePower ) ; + signal.y += (noise.x*2.0-1.0)*signalNoiseAmount; + signal.z += (noise.y*2.0-1.0)*signalNoiseAmount; + } else { + //type 3 + const vec2 noise = n4rand_bw( pn_,t, 1.0-signalNoisePower )*signalNoiseAmount ; + signal.y *= noise.x; + signal.z *= noise.y; + signal.x += (noise.x*2.0-1.0)*0.05; + } + } + + //2nd part with noise, tail and yiq col shift + if (VHS_TapeNoise){ + + //here is normilized p (0..1) + float tn = texture(SamplerTape, pn).x; + signal.x = bms(signal.x, tn*tapeNoiseAmount ).x; + // float tn = tapeNoise(pn, t*tapeNoiseSpeed)*tapeNoiseAmount; + + //tape noise tail + const int tailLength=10; //TODO adjustable + + for(int j = 0; j < tailLength % 1023; j++){ + + const float jj = float(j); + const vec2 d = vec2(pn.x-ONEXN*jj,pn.y); + tn = textureLod(SamplerTape, vec2(d), 0. ).x; + // tn = texture(SamplerTape, d).x; + // tn = tapeNoise(vec2(pn.x-ONEXN*i,pn.y), t*tapeNoiseSpeed)*tapeNoiseAmount; + + float fadediff = 0.0; + + //for tails length difference +// if(__RENDERER__ == 0x0A100 || __RENDERER__ == 0x0B000) { +// fadediff = textureLod(SamplerTape, vec2(d), 0.).a; //hash12(d); +// } + +// if(__RENDERER__ == 0x09300 || __RENDERER__ >= 0x10000) { + fadediff = texture(SamplerTape, d).a; //hash12(d); +// } + + if( tn > 0.8 ){ + float nsx = 0.0; //new signal x + const float newlength = float(tailLength)*(1.0-fadediff); //tail lenght diff + if( jj <= newlength ) nsx = 1.0-( jj/ newlength ); //tail + signal.x = bms(signal.x, nsx*tapeNoiseAmount).x; + } + } + + //tape noise color shift + if(distShift>0.4){ + // float tnl = tapeNoiseLines(vec2(0.0,pn.y), t*tapeNoiseSpeed)*tapeNoiseAmount; + const float tnl = texture(SamplerTape, pn).y;//tapeNoiseLines(vec2(0.0,pn.y), t*tapeNoiseSpeed)*tapeNoiseAmount; + signal.y *= 1.0/distShift;//tnl*0.1;//*distShift;//*signal.x; + signal.z *= 1.0/distShift;//*distShift;//*signal.x; + + } +} + + //back to rgb color space + //signal has negative values + col = yiq2rgb(signal); + + //TODO put it into 2nd pass + if (VHS_ScanLines){ + col *= scanLines(txcoord.xy, t); + } + + //fisheye cutoff / outside fisheye + //helps to remove noise outside the fisheye + if (VHS_FishEye){ + + p = txcoord.xy; + + float far; + const vec2 hco = vec2(ONE_X*cutoffX, ONE_Y*cutoffY) * 0.25; //hard cuttoff x + const vec2 sco = vec2(ONE_X*cutoffFadeX, ONE_Y*cutoffFadeY) * 0.25; //soft cuttoff x + + //hard cutoff + if( p.x<=(0.0+hco.x) || p.x>=(1.0-hco.x) || p.y<=(0.0+hco.y) || p.y>=(1.0-hco.y) ){ + col = vec3(0.0,0.0,0.0); + } else { + //fades + + if( //X + (p.x>(0.0+hco.x) && p.x<(0.0+(sco.x+hco.x) )) || (p.x>(1.0-(sco.x+hco.x)) && p.x<(1.0-hco.x)) + ){ + if(p.x<0.5) far = (0.0-hco.x+p.x)/(sco.x); + else + far = (1.0-hco.x-p.x)/(sco.x); + + col *= float(far).xxx; + }; + + if( //Y + (p.y>(0.0+hco.y) && p.y<(0.0+(sco.y+hco.y) )) || (p.y>(1.0-(sco.y+hco.y)) && p.y<(1.0-hco.y)) + ){ + if(p.y<0.5) far = (0.0-hco.y+p.y)/(sco.y); + else + far = (1.0-hco.y-p.y)/(sco.y); + + col *= float(far).xxx; + } + } + } + + // col = texture(SamplerTape, txcoord.xy).x; + + FragColor = vec4(col, 1.0); +// FragColor = (VHS_TapeNoise && params.FrameDirection < 0) ? FragColor + (vec4(texture(tape, txcoord).g)) * 2. : FragColor; +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_Forth.slang b/vhs/shaders/VHSPro/VHSPro_Forth.slang new file mode 100644 index 0000000..93b1858 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_Forth.slang @@ -0,0 +1,56 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#define SamplerColorVHS second +#define _FeedbackTex third + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 texcoord; + +void main() +{ + gl_Position = global.MVP * Position; + texcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 texcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D second; +layout(set = 0, binding = 3) uniform sampler2D third; + +#include "VHSPro_functions.inc" + +void main() +{ + // needed to add distortion here or the trails don't match up to the image + vec2 p = texcoord; + //distortions + if (VHS_FishEye){ + p = fishEye(p, fisheyeSize, fisheyeBend); // p = fishEye(p, 1.2, 2.0); + // return vec4( fract(p*5.0)/2.5, 1.0, 1.0); //debug + } + vec3 col = texture( SamplerColorVHS, texcoord).rgb; //curent frame + const vec3 fbb = texture( _FeedbackTex, p).rgb; //feedback buffer + + if (VHS_Feedback){ + col = bm_screen(col, fbb*feedbackAmp); + if (feedbackDebug){ + col = fbb; + } + } + + FragColor = vec4(col, 1.0); +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_LastFrame.slang b/vhs/shaders/VHSPro/VHSPro_LastFrame.slang new file mode 100644 index 0000000..b7d787c --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_LastFrame.slang @@ -0,0 +1,49 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#define SamplerColorVHS second +#define _FeedbackTex Source + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 texcoord; + +void main() +{ + gl_Position = global.MVP * Position; + texcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 texcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D second; + +#include "VHSPro_functions.inc" + +void main() +{ + vec3 col = texture( SamplerColorVHS, texcoord).rgb; //curent frame + const vec3 fbb = texture( _FeedbackTex, texcoord).rgb; //feedback buffer + + if (VHS_Feedback){ + col = bm_screen(col, fbb*feedbackAmp); + if (feedbackDebug){ + col = fbb; + } + } + + FragColor = vec4(col, 1.0); +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_Second.slang b/vhs/shaders/VHSPro/VHSPro_Second.slang new file mode 100644 index 0000000..0eb3484 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_Second.slang @@ -0,0 +1,152 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#define SamplerColorVHS Source + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 txcoord; + +void main() +{ + gl_Position = global.MVP * Position; + txcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 txcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; + +#include "VHSPro_functions.inc" + +void main() +{ + const float t = float(params.FrameCount) * 0.25;//_Time.y; + vec2 p = txcoord.xy; + float SLN = screenLinesNum; //TODO use only SLN + + //basically if its 0 -> set it to fullscreen + if(SLN==0.0) SLN = _ScreenParams.y; + + //TODO maybe make it based on num of lines? and height ? + //TODO make switch between real pixels and pixelated pixels! + // ONE_X = 1.0 / screenLinesNum; + + float ONE_X = 1.0 / _ScreenParams.x; // 1px + ONE_X *= bleedAmount; // longer tails, more bleeding, default 1. + + //distortions + if (VHS_FishEye){ + p = fishEye(p, fisheyeSize, fisheyeBend); // p = fishEye(p, 1.2, 2.0); + // return vec4( fract(p*5.0)/2.5, 1.0, 1.0); //debug + } + + int bleedLength = 21; + + if((VHS_BleedMode == 0 || VHS_BleedMode == 1 || VHS_BleedMode == 3)) + { + bleedLength = 25; + } + + if((VHS_BleedMode == 2 || VHS_BleedMode == 4)) + { + bleedLength = 32; + } + +#include "taps.inc" + + //Bleeding + vec3 signal = vec3(0.0,0.0,0.0); + + if (VHS_Bleed){ + + vec3 norm = vec3(0.0,0.0,0.0); + vec3 adj = vec3(0.0,0.0,0.0); + + const int taps = bleedLength-4; + //int taps = bleedLength; //RetroArch + + for (int ii = 0; float(ii) < mod(float(taps) , float(1023)); ii++){ + + const float offset = float(ii); + const vec3 sums = fetch_offset(offset - float(taps), ONE_X) + + fetch_offset(float(taps) - offset, ONE_X) ; + + adj = vec3(luma_filter[ii+3], chroma_filter[ii], chroma_filter[ii]); + //adj = vec3(luma_filter[ii], chroma_filter[ii], chroma_filter[ii]); //RetroArch + + signal += sums * adj; + norm += adj; + + } + + adj = vec3(luma_filter[taps], chroma_filter[taps], chroma_filter[taps]); + + signal += t2d(fixCoord) * adj; + norm += adj; + signal = signal / norm; + } else { + //no bleeding + signal = t2d(p); + } + + //[Signal Tweak] + if (VHS_SignalTweak){ + + //adjust + signal.x += signalAdjustY; + signal.y += signalAdjustI; + signal.z += signalAdjustQ; + + //shift + signal.x *= signalShiftY; + signal.y *= signalShiftI; + signal.z *= signalShiftQ; + + // //test YIQ + // signal.x = 0.5; + // signal.y = p.x*2.0-1.0; + // signal.z = p.y*2.0-1.0; + + //signal noise + // vec2 noise = n4rand_bw( p,t, 1.0-signalNoisePower )*signalNoiseAmount ; + // signal.y *= noise.x; + // signal.z *= noise.y; + + + //phase - it cant be dont coz of intervals + // signal.x = fract( (signal.x +1.0)*0.5f )*2.0f - 1.0f ; + //signal.y = fract( (signal.y +1.0)*0.5f )*2.0f - 1.0f ; + //signal.z = fract( (signal.z +1.0)*0.5f )*2.0f - 1.0f ; + } + + vec3 rgb = yiq2rgb(signal); + + if (VHS_SignalTweak){ + if(gammaCorection!=1.0) rgb = pow(abs(rgb), vec3(gammaCorection)); //vec3(gammaCorection).rgb + } + + //cut trash after fish eye + // if( p.x<0. || p.x>1. || p.y<0. || p.y>1.){ + // rgb *= 0.0; + // } + + //TODO maybe on yiq channel + if (VHS_Vignette){ + rgb *= vignette(p, t*vignetteSpeed); //TODO params //txcoord.xy + } + + FragColor = vec4(rgb, 1.0); +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_Tape.slang b/vhs/shaders/VHSPro/VHSPro_Tape.slang new file mode 100644 index 0000000..84de853 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_Tape.slang @@ -0,0 +1,68 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#define SamplerColorVHS Original + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 txcoord; + +void main() +{ + gl_Position = global.MVP * Position; + txcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 txcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Original; + +#include "VHSPro_functions.inc" + +void main() +{ + const float t = float(params.FrameCount) * 0.025; + vec2 p = txcoord.xy; + + p.y=1-p.y; + + const vec2 p_ = p*_ScreenParams; + + float ns = 0.0; //signal noise //tex2D(_TapeTex, p); + float nt = 0.0; //tape noise + float nl = 0.0; //lines for tape noise + float ntail = 0.0; //tails values for tape noise + + if (VHS_TapeNoise) { + + //here is normilized p (0..1) + nl = tapeNoiseLines(p, t*tapeNoiseSpeed)*1.0;//tapeNoiseAmount; + nt = tapeNoise(nl, p, t*tapeNoiseSpeed)*1.0;//tapeNoiseAmount; + ntail = hash12(p+ vec2(0.01,0.02) ); + } + + if (VHS_LineNoise) { + ns += lineNoise(p_, t*lineNoiseSpeed)*lineNoiseAmount; + // col += lineNoise(pn_, t*lineNoiseSpeed)*lineNoiseAmount;//i.uvn + } + + //y noise from yiq + if (VHS_FilmGrain) { + //cheap n ok atm + ns += filmGrain((p_-0.5*_ScreenParams.xy)*0.5, t, filmGrainPower ) * filmGrainAmount; + } + + FragColor = vec4(nt,nl,ns,ntail); +} \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_Third.slang b/vhs/shaders/VHSPro/VHSPro_Third.slang new file mode 100644 index 0000000..4d77477 --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_Third.slang @@ -0,0 +1,66 @@ +#version 450 + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; +} params; + +#include "VHSPro_params.inc" +#include "VHSPro_constants.inc" + +#define SamplerColorVHS Original +#define VHS_InputB OriginalHistory1 + +#pragma stage vertex +layout(location = 0) in vec4 Position; +layout(location = 1) in vec2 TexCoord; +layout(location = 0) out vec2 texcoord; + +void main() +{ + gl_Position = global.MVP * Position; + texcoord = TexCoord; +} + +#pragma stage fragment +layout(location = 0) in vec2 texcoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Original; +layout(set = 0, binding = 3) uniform sampler2D OriginalHistory1; +layout(set = 0, binding = 4) uniform sampler2D PassFeedback0; + +#define _FeedbackTex PassFeedback0 + +#include "VHSPro_functions.inc" + +void main() +{ + vec2 p = texcoord.xy; + const float one_x = 1.0/_ScreenParams.x; + vec3 fc = texture( SamplerColorVHS, texcoord).rgb; // curent frame + + //new feedback + const vec3 fl = texture( VHS_InputB, texcoord).rgb; //last frame without feedback + float diff = abs(fl.x-fc.x + fl.y-fc.y + fl.z-fc.z)/3.0; //dfference between frames + if(diffscanLineWidth) scans = 1.; else scans = 0.; + + float t_sl = 0.0; + //if lines aren't floating -> scanlines also shudn't + if (VHS_LinesFloat) { + t_sl = t*linesFloatSpeed; + } + + //expensive but better + float scans = 0.5*(cos( (p.y*(screenLinesNum * 0.5)+t_sl)*2.0*PI) + 1.0); + scans = pow(scans, scanLineWidth); + return 1.0 - scans; +} + +float gcos(vec2 uv, float s, float p) +{ + return (cos( uv.y * PI * 2.0 * s + p)+1.0)*0.5; +} + +//mw - maximum width +//wcs = widthChangeSpeed +//lfs = line float speed = .5 +//lf phase = line float phase = .0 +vec2 stretch(vec2 uv, float t, float mw, float wcs, float lfs, float lfp){ + + const float SLN = screenLinesNum; //TODO use only SLN + //width change + const float tt = t*wcs; //widthChangeSpeed + const float t2 = tt-fmod(tt, 0.5); + + //float dw = hash42( vec2(0.01, t2) ).x ; //on t and not on y + float w = gcos(uv, 2.0*(1.0-fract(t2)), PI-t2) * clamp( gcos(uv, fract(t2), t2) , 0.5, 1.0); + //w = clamp(w,0.,1.); + w = floor(w*mw)/mw; + w *= mw; + //get descreete line number + float ln = (1.0-fract(t*lfs + lfp)) *screenLinesNum; + ln = ln - fract(ln); + // float ln = (1.-fmod(t*lfs + lfp, 1.))*SLN; + // ln = ln - fmod(ln, 1.); //descreete line number + + //ln = 10.; + //w = 4.; + + //////stretching part/////// + + const float oy = 1.0/SLN; //TODO global + const float sh2 = 1.0 - fmod(ln, w)/w; // shift 0..1 + + // #if VHS_LINESFLOAT_ON + // float sh = fmod(t, 1.); + // uv.y = floor( uv.y *SLN +sh )/SLN - sh/SLN; + // #else + // uv.y = floor( uv.y *SLN )/SLN; + // #endif + + // uv.y = floor( uv.y *SLN )/SLN ; + + const float slb = SLN / w; //screen lines big + + //TODO finish + // #if VHS_LINESFLOAT_ON + + // if(uv.yoy*(ln-w)) ////if(uv.y>oy*ln && uv.yoy*(ln-w)) ////if(uv.y>oy*ln && uv.y 0.0) bind = sqrt(dot(m, m));//stick to corners + else {if (prop < 1.0) bind = m.x; else bind = m.x;}//stick to borders + + if (power > 0.0) //fisheye + uv = m + normalize(d) * tan(r * power) * bind / tan( bind * power); + else if (power < 0.0) //antifisheye + uv = m + normalize(d) * atan(r * -power * 10.0) * bind / atan(-power * bind * 10.0); + else uv = (uv*_ScreenParams.xy) /_ScreenParams.x; + + uv.y *= prop; + } + + //adjust size + // uv -= vec2(0.5,0.5); + // uv *= size; + // uv += vec2(0.5,0.5); + + return uv; +} + +//pulse vignette +float vignette(vec2 uv, float t) +{ + const float vigAmt = 2.5+0.1*sin(t + 5.0*cos(t*5.0)); + float c = (1.0-vigAmt*(uv.y-0.5)*(uv.y-0.5))*(1.0-vigAmt*(uv.x-0.5)*(uv.x-0.5)); + c = pow(abs(c), vignetteAmount); //expensive! + return c; +} + +vec3 t2d(vec2 p) +{ + return rgb2yiq( texture (SamplerColorVHS, p ).rgb ); +} + +vec3 yiqDist(vec2 uv, float m, float t) +{ + m *= 0.0001; // float m = 0.0009; + vec3 offsetX = vec3( uv.x, uv.x, uv.x ); + + offsetX.r += rnd_rd(vec2(t*0.03, uv.y*0.42)) * 0.001 + sin(rnd_rd(vec2(t*0.2, uv.y)))*m; + offsetX.g += rnd_rd(vec2(t*0.004,uv.y*0.002)) * 0.004 + sin(t*9.0)*m; + // offsetX.b = uv.y + rnd_rd(vec2(cos(t*0.01),sin(uv.y)))*m; + // offsetX.b = uv.y + rand_rd(vec2(cos(t*0.01),sin(uv.y)))*m; + + vec3 signal = vec3(0.0, 0.0, 0.0); + //it cud be optimized / but hm + signal.x = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.r, uv.y) ).rgb ).x; + signal.y = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.g, uv.y) ).rgb ).y; + signal.z = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.b, uv.y) ).rgb ).z; + + // signal = yiq2rgb(col); + return signal; +} + +#define fixCoord (p - vec2( 0.5 * PixelSize.x, .0)) +#define fetch_offset(offset, one_x) t2d(fixCoord + vec2( (offset) * (ONE_X), 0.0)); + +vec3 bm_screen(vec3 a, vec3 b){ return 1.0- (1.0-a)*(1.0-b); } \ No newline at end of file diff --git a/vhs/shaders/VHSPro/VHSPro_params.inc b/vhs/shaders/VHSPro/VHSPro_params.inc new file mode 100644 index 0000000..65967fb --- /dev/null +++ b/vhs/shaders/VHSPro/VHSPro_params.inc @@ -0,0 +1,246 @@ +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + float screenLinesNum, VHS_Bleed_toggle, VHS_BleedMode_select, bleedAmount, VHS_FishEye_toggle, + VHS_FishEye_Hyperspace_toggle, fisheyeBend, cutoffX, cutoffY, cutoffFadeX, cutoffFadeY, + VHS_Vignette_toggle, vignetteAmount, vignetteSpeed, noiseLinesLum, noiseQuantizeX, + VHS_FilmGrain_toggle, filmGrainAmount, VHS_YIQNoise_toggle, signalNoiseType_select, + signalNoiseAmount, signalNoisePower, VHS_LineNoise_toggle, lineNoiseAmount, lineNoiseSpeed, + VHS_TapeNoise_toggle, tapeNoiseTH, tapeNoiseAmount, tapeNoiseSpeed, VHS_ScanLines_toggle, + scanLineWidth, VHS_LinesFloat_toggle, linesFloatSpeed, VHS_Stretch_toggle,VHS_Jitter_H_toggle, + jitterHAmount, VHSJitter_V_toggle, jitterVAmount, jitterVSpeed, VHS_Twitch_H_toggle, + twitchHFreq, VHS_Twitch_V_toggle, twitchVFreq, VHS_SignalTweak_toggle, signalAdjustY, + signalAdjustI, signalAdjustQ, signalShiftY, signalShiftI, signalShiftQ, gammaCorection, + VHS_Feedback_toggle, feedbackAmount, feedbackFade, feedbackThresh, feedbackColor_R, + feedbackColor_G, feedbackColor_B, feedbackDebug_toggle, noiseLinesNum; +} global; + +#pragma parameter screenLinesNum "Screen Resolution [VHSPro]" 1080.0 1.0 2160.0 16.0 +#define screenLinesNum global.screenLinesNum +// "Screen Resolution (in lines).\nChange screenLinesRes in Preprocessor Definitions to have the same value as this." + +#pragma parameter VHS_Bleed_toggle "Toggle Bleeding [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_Bleed = bool(global.VHS_Bleed_toggle); +// "Enables beam screen bleeding (makes the image blurry)." + +#pragma parameter VHS_BleedMode_select "Bleeding Mode [VHSPro]" 1.0 1.0 5.0 1.0 +int VHS_BleedMode = int(global.VHS_BleedMode_select); +// "Toggles between different bleeding modes." + +#pragma parameter bleedAmount "Bleed Stretch [VHSPro]" 0.5 0.0 15.0 0.1 +#define bleedAmount global.bleedAmount +// "Length of the bleeding." // default value of 1.0 was too much + +#pragma parameter VHS_FishEye_toggle "Toggle Fisheye [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_FishEye = bool(global.VHS_FishEye_toggle); +// "Enables a CRT Curvature." // defaulting to off + +#pragma parameter VHS_FishEye_Hyperspace_toggle "Toggle Fisheye Hyperspace [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_FishEye_Hyperspace = bool(global.VHS_FishEye_Hyperspace_toggle); +// "Changes the curvature to look like some sort of hyperspace warping." + +#pragma parameter fisheyeBend "Fisheye Bend [VHSPro]" 0.5 0.0 3.0 0.05 +#define fisheyeBend global.fisheyeBend +// "Curvature of the CRT." // default value of 2.0 was way too high + +#pragma parameter cutoffX "Fisheye Cutoff X [VHSPro]" 2.0 0.0 50.0 1.0 +#define cutoffX global.cutoffX +// "Cutoff of the Horizontal Borders." + +#pragma parameter cutoffY "Fisheye Cutoff Y [VHSPro]" 3.0 0.0 50.0 1.0 +#define cutoffY global.cutoffY +// "Cutoff of the Vertical Borders." + +#pragma parameter cutoffFadeX "Fisheye Cutoff Fade X [VHSPro]" 25.0 0.0 50.0 1.0 +#define cutoffFadeX global.cutoffFadeX +// "Size of the Horizontal gradient cutoff." + +#pragma parameter cutoffFadeY "Fisheye Cutoff Fade Y [VHSPro]" 25.0 0.0 50.0 1.0 +#define cutoffFadeY global.cutoffFadeY +// "Size of the Vertical gradient cutoff." + +#pragma parameter VHS_Vignette_toggle "Toggle Vignette [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_Vignette = bool(global.VHS_Vignette_toggle); +// "Enables screen vignetting" // default to 'on' to make up for lost fisheye + +#pragma parameter vignetteAmount "Vignette Amount [VHSPro]" 0.3 0.0 5.0 0.05 +#define vignetteAmount global.vignetteAmount +// "Strength of the vignette." // default value of 1.0 was way too much + +#pragma parameter vignetteSpeed "Vignette Pulse Speed [VHSPro]" 1.0 0.0 5.0 0.05 +#define vignetteSpeed global.vignetteSpeed +// "Speed of the vignette pulsing. (Setting it to 0 makes it stop pulsing)" + +#pragma parameter noiseLinesNum "Vertical Resolution [VHSPro]" 240.0 1.0 1080.0 16.0 +#define noiseLinesNum global.noiseLinesNum +// "Noise Resolution (in lines).\nChange noiseLinesRes in Preprocessor Definitions to have the same value as this." + +#pragma parameter noiseQuantizeX "Quantize Noise X [VHSPro]" 0.0 0.0 1.0 0.01 +#define noiseQuantizeX global.noiseQuantizeX +// "Makes the noise longer or shorter." + +#pragma parameter VHS_FilmGrain_toggle "Toggle Film Grain [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_FilmGrain = bool(global.VHS_FilmGrain_toggle); +// "Enables a Film Grain on the screen." + +#pragma parameter filmGrainAmount "Film Grain Alpha [VHSPro]" 0.5 0.0 1.0 0.01 +float filmGrainAmount = global.filmGrainAmount * 0.1; +// "Intensity of the Film Grain." // default was too low + +#pragma parameter VHS_YIQNoise_toggle "Toggle Signal Noise [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_YIQNoise = bool(global.VHS_YIQNoise_toggle); +// "Adds noise to the YIQ Signal, causing a Pink (or green) noise." + +#pragma parameter signalNoiseType_select "Signal Noise Type [VHSPro]" 1.0 1.0 3.0 1.0 +int signalNoiseType = int(global.signalNoiseType_select); +// "Signal Noise Type [VHS Pro]" + +#pragma parameter signalNoiseAmount "Signal Noise Amount [VHSPro]" 0.10 0.0 1.0 0.01 +#define signalNoiseAmount global.signalNoiseAmount +// "Amount of the signal noise." + +#pragma parameter signalNoisePower "Signal Noise Power [VHSPro]" 0.75 0.0 1.0 0.01 +#define signalNoisePower global.signalNoisePower +// "Power of the signal noise. Higher values will make it green, lower values will make it more pink." + +#pragma parameter VHS_LineNoise_toggle "Toggle Line Noise [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_LineNoise = bool(global.VHS_LineNoise_toggle); +// "Enables blinking line noise in the image." + +#pragma parameter lineNoiseAmount "Line Noise Amount [VHSPro]" 1.0 0.0 10.0 0.1 +#define lineNoiseAmount global.lineNoiseAmount +// "Intensity of the line noise." + +#pragma parameter lineNoiseSpeed "Line Noise Speed [VHSPro]" 5.0 0.0 10.0 0.1 +#define lineNoiseSpeed global.lineNoiseSpeed +// "Speed of the line noise blinking delay." + +#pragma parameter VHS_TapeNoise_toggle "Toggle Tape Noise [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_TapeNoise = bool(global.VHS_TapeNoise_toggle); +// "Adds scrolling noise like in old VHS Tapes." + +#pragma parameter tapeNoiseTH "Tape Noise Amount [VHSPro]" 0.63 0.0 1.5 0.01 +#define tapeNoiseTH global.tapeNoiseTH +// "Intensity of Tape Noise in the image." + +#pragma parameter tapeNoiseAmount "Tape Noise Alpha [VHSPro]" 0.05 0.0 1.5 0.01 +#define tapeNoiseAmount global.tapeNoiseAmount +// "Amount of Tape Noise in the image." + +#pragma parameter tapeNoiseSpeed "Tape Noise Speed [VHSPro]" 1.0 -1.5 1.5 0.05 +#define tapeNoiseSpeed global.tapeNoiseSpeed +// "Scrolling speed of the Tape Noise." + +#pragma parameter VHS_ScanLines_toggle "Toggle Scanlines [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_ScanLines = bool(global.VHS_ScanLines_toggle); +// "Enables TV/CRT Scanlines." + +#pragma parameter scanLineWidth "Scanlines Width [VHSPro]" 10.0 0.0 20.0 0.25 +#define scanLineWidth global.scanLineWidth +// "Width of the Scanlines." + +#pragma parameter VHS_LinesFloat_toggle "Toggle Lines Float [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_LinesFloat = bool(global.VHS_LinesFloat_toggle); +// "Makes the lines of the screen floats up or down. Works best with low Screen Lines resolutions." + +#pragma parameter linesFloatSpeed "Lines Float Speed [VHSPro]" 1.0 -3.0 3.0 0.1 +#define linesFloatSpeed global.linesFloatSpeed +// "Speed (and direction) of the floating lines." + +#pragma parameter VHS_Stretch_toggle "Toggle Stretch Noise" 1.0 0.0 1.0 1.0 +bool VHS_Stretch = bool(global.VHS_Stretch_toggle); +// "Enables a stretching noise that scrolls up and down on the Image, simulating magnetic interference of VHS tapes." + +#pragma parameter VHS_Jitter_H_toggle "Toggle Interlacing [VHSPro]" 1.0 0.0 1.0 1.0 +bool VHS_Jitter_H = bool(global.VHS_Jitter_H_toggle); +// "Enables interlacing." + +#pragma parameter jitterHAmount "Interlacing Amount [VHSPro]" 0.15 0.0 5.0 0.05 +#define jitterHAmount global.jitterHAmount +// "Strength of the Interlacing." //default 0.50 was too much + +#pragma parameter VHSJitter_V_toggle "Toggle Jitter [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_Jitter_V = bool(global.VHSJitter_V_toggle); +// "Adds vertical jittering noise." + +#pragma parameter jitterVAmount "Jitter Amount [VHSPro]" 7.5 0.0 15.0 0.1 +#define jitterVAmount global.jitterVAmount +// "Amount of the vertical jittering noise." //default 1.0 was invisible + +#pragma parameter jitterVSpeed "Jitter Speed [VHSPro]" 1.0 0.0 5.0 0.1 +#define jitterVSpeed global.jitterVSpeed +// "Speed of the vertical jittering noise." + +#pragma parameter VHS_Twitch_H_toggle "Toggle Horizontal Twitch [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_Twitch_H = bool(global.VHS_Twitch_H_toggle); +// "Makes the image twitches horizontally in certain timed intervals." + +#pragma parameter twitchHFreq "Horizontal Twitch Frequency [VHSPro]" 1.0 0.0 5.0 0.1 +#define twitchHFreq global.twitchHFreq +// "Frequency of time in which the image twitches horizontally." + +#pragma parameter VHS_Twitch_V_toggle "Toggle Vertical Twitch [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_Twitch_V = bool(global.VHS_Twitch_V_toggle); +// "Makes the image twitches vertically in certain timed intervals." + +#pragma parameter twitchVFreq "Vertical Twitch Frequency [VHSPro]" 1.0 0.0 5.0 0.1 +#define twitchVFreq global.twitchVFreq +// "Frequency of time in which the image twitches vertically." + +#pragma parameter VHS_SignalTweak_toggle "Toggle Signal Tweak [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_SignalTweak = bool(global.VHS_SignalTweak_toggle); +// "Tweak the values of the YIQ signal." + +#pragma parameter signalAdjustY "Signal Shift Y [VHSPro]" 0.0 -0.25 0.25 0.01 +#define signalAdjustY global.signalAdjustY +// "Shifts/Tweaks the Luma part of the signal." + +#pragma parameter signalAdjustI "Signal Shift I [VHSPro]" 0.0 -0.25 0.25 0.01 +#define signalAdjustI global.signalAdjustI +// "Shifts/Tweaks the Chroma part of the signal." + +#pragma parameter signalAdjustQ "Signal Shift Q [VHSPro]" 0.0 -0.25 0.25 0.01 +#define signalAdjustQ global.signalAdjustQ +// "Shifts/Tweaks the Chroma part of the signal." + +#pragma parameter signalShiftY "Signal Adjust Y [VHSPro]" 1.0 -2.0 2.0 0.05 +#define signalShiftY global.signalShiftY +// "Adjusts the Luma part of the signal." + +#pragma parameter signalShiftI "Signal Adjust I [VHSPro]" 1.0 -2.0 2.0 0.05 +#define signalShiftI global.signalShiftI +// "Adjusts the Chroma part of the signal." + +#pragma parameter signalShiftQ "Signal Adjust Q [VHSPro]" 1.0 -2.0 2.0 0.05 +#define signalShiftQ global.signalShiftQ +// "Adjusts the Chroma part of the signal." + +#pragma parameter gammaCorection "Signal Gamma Correction [VHSPro]" 1.0 0.0 2.0 0.05 +#define gammaCorection global.gammaCorection +// "Gamma corrects the image." + +#pragma parameter VHS_Feedback_toggle "Toggle Phosphor Trails [VHSPro]" 0.0 0.0 1.0 1.0 +bool VHS_Feedback = bool(global.VHS_Feedback_toggle); +// "Enables phosphor-trails from old CRT monitors." + +#pragma parameter feedbackAmount "Input Amount [VHSPro]" 2.0 0.0 3.0 0.05 +#define feedbackAmount global.feedbackAmount +// "Amount of Phosphor Trails." + +#pragma parameter feedbackFade "Phosphor Fade [VHSPro]" 0.82 0.0 1.0 0.01 +#define feedbackFade global.feedbackFade +// "Fade-time of the phosphor-trails." + +#pragma parameter feedbackThresh "Input Cutoff [VHSPro]" 0.1 0.0 1.0 0.01 +#define feedbackThresh global.feedbackThresh +// "Cutoff of the trail." + +#pragma parameter feedbackColor_R "Red Tint of Phosphor Trail" 1.0 0.0 1.0 0.01 +#pragma parameter feedbackColor_G "Green Tint of Phosphor Trail" 0.5 0.0 1.0 0.01 +#pragma parameter feedbackColor_B "Blue Tint of Phosphor Trail" 0.0 0.0 1.0 0.01 +vec3 feedbackColor = vec3(global.feedbackColor_R, global.feedbackColor_G, global.feedbackColor_B); +// "Color of the trail." + +#pragma parameter feedbackDebug_toggle "Toggle Debug Trail [VHSPro]" 0.0 0.0 1.0 1.0 +bool feedbackDebug = bool(global.feedbackDebug_toggle); +// "Enables the visualization of the phosphor-trails only." \ No newline at end of file diff --git a/vhs/shaders/VHSPro/feedback.slang b/vhs/shaders/VHSPro/feedback.slang new file mode 100644 index 0000000..75b5868 --- /dev/null +++ b/vhs/shaders/VHSPro/feedback.slang @@ -0,0 +1,42 @@ +#version 450 + +layout(push_constant) uniform Push +{ + float mixfactor; +} param; + +#pragma parameter mixfactor "Motionblur Fadeout" 0.75 0.0 1.0 0.01 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; + vec4 OutputSize; + vec4 OriginalSize; + vec4 SourceSize; +} global; + +#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; +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 2) uniform sampler2D Source; +layout(set = 0, binding = 3) uniform sampler2D PassFeedback0; + +void main() +{ + vec4 current = pow(texture(Source, vTexCoord), vec4(2.2)); + vec4 fdback = pow(texture(PassFeedback0, vTexCoord), vec4(2.2)); + vec4 mixed = (1.0 - param.mixfactor) * current + param.mixfactor * fdback; + + FragColor = pow(mixed, vec4(1.0 / 2.2)); +} diff --git a/vhs/shaders/VHSPro/taps.inc b/vhs/shaders/VHSPro/taps.inc new file mode 100644 index 0000000..b88d25a --- /dev/null +++ b/vhs/shaders/VHSPro/taps.inc @@ -0,0 +1,318 @@ + float luma_filter[33] = { + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000 + }; + + float chroma_filter[33] = { + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000, + 0.000000000 + }; + + if (VHS_BleedMode == 0 || VHS_BleedMode == 3){ //Three Phase and Three Phase (RetroArch) + luma_filter[0] = -0.000012020; + luma_filter[1] = -0.000022146; + luma_filter[2] = -0.000013155; + luma_filter[3] = -0.000012020; + luma_filter[4] = -0.000049979; + luma_filter[5] = -0.000113940; + luma_filter[6] = -0.000122150; + luma_filter[7] = -0.000005612; + luma_filter[8] = 0.000170516; + luma_filter[9] = 0.000237199; + luma_filter[10] = 0.000169640; + luma_filter[11] = 0.000285688; + luma_filter[12] = 0.000984574; + luma_filter[13] = 0.002018683; + luma_filter[14] = 0.002002275; + luma_filter[15] = -0.000909882; + luma_filter[16] = -0.007049081; + luma_filter[17] = -0.013222860; + luma_filter[18] = -0.012606931; + luma_filter[19] = 0.002460860; + luma_filter[20] = 0.035868225; + luma_filter[21] = 0.084016453; + luma_filter[22] = 0.135563500; + luma_filter[23] = 0.175261268; + luma_filter[24] = 0.190176552; + + chroma_filter[0] = -0.000118847; + chroma_filter[1] = -0.000271306; + chroma_filter[2] = -0.000502642; + chroma_filter[3] = -0.000930833; + chroma_filter[4] = -0.001451013; + chroma_filter[5] = -0.002064744; + chroma_filter[6] = -0.002700432; + chroma_filter[7] = -0.003241276; + chroma_filter[8] = -0.003524948; + chroma_filter[9] = -0.003350284; + chroma_filter[10] = -0.002491729; + chroma_filter[11] = -0.000721149; + chroma_filter[12] = 0.002164659; + chroma_filter[13] = 0.006313635; + chroma_filter[14] = 0.011789103; + chroma_filter[15] = 0.018545660; + chroma_filter[16] = 0.026414396; + chroma_filter[17] = 0.035100710; + chroma_filter[18] = 0.044196567; + chroma_filter[19] = 0.053207202; + chroma_filter[20] = 0.061590275; + chroma_filter[21] = 0.068803602; + chroma_filter[22] = 0.074356193; + chroma_filter[23] = 0.077856564; + chroma_filter[24] = 0.079052396; + } + + else if (VHS_BleedMode == 1) { //Old Three-Phase + luma_filter[0] = -0.000071070; + luma_filter[1] = -0.000032816; + luma_filter[2] = 0.000128784; + luma_filter[3] = 0.000134711; + luma_filter[4] = -0.000226705; + luma_filter[5] = -0.000777988; + luma_filter[6] = -0.000997809; + luma_filter[7] = -0.000522802; + luma_filter[8] = 0.000344691; + luma_filter[9] = 0.000768930; + luma_filter[10] = 0.000275591; + luma_filter[11] = -0.000373434; + luma_filter[12] = 0.000522796; + luma_filter[13] = 0.003813817; + luma_filter[14] = 0.007502825; + luma_filter[15] = 0.006786001; + luma_filter[16] = -0.002636726; + luma_filter[17] = -0.019461182; + luma_filter[18] = -0.033792479; + luma_filter[19] = -0.029921972; + luma_filter[20] = 0.005032552; + luma_filter[21] = 0.071226466; + luma_filter[22] = 0.151755921; + luma_filter[23] = 0.218166470; + luma_filter[24] = 0.243902439; + + chroma_filter[0] = 0.001845562; + chroma_filter[1] = 0.002381606; + chroma_filter[2] = 0.003040177; + chroma_filter[3] = 0.003838976; + chroma_filter[4] = 0.004795341; + chroma_filter[5] = 0.005925312; + chroma_filter[6] = 0.007242534; + chroma_filter[7] = 0.008757043; + chroma_filter[8] = 0.010473987; + chroma_filter[9] = 0.012392365; + chroma_filter[10] = 0.014503872; + chroma_filter[11] = 0.016791957; + chroma_filter[12] = 0.019231195; + chroma_filter[13] = 0.021787070; + chroma_filter[14] = 0.024416251; + chroma_filter[15] = 0.027067414; + chroma_filter[16] = 0.029682613; + chroma_filter[17] = 0.032199202; + chroma_filter[18] = 0.034552198; + chroma_filter[19] = 0.036677005; + chroma_filter[20] = 0.038512317; + chroma_filter[21] = 0.040003044; + chroma_filter[22] = 0.041103048; + chroma_filter[23] = 0.041777517; + chroma_filter[24] = 0.042004791; + } + + else if (VHS_BleedMode == 2) { //Two-Phase + luma_filter[0] = -0.000205844; + luma_filter[1] = -0.000149453; + luma_filter[2] = -0.000051693; + luma_filter[3] = 0.000000000; + luma_filter[4] = -0.000066171; + luma_filter[5] = -0.000245058; + luma_filter[6] = -0.000432928; + luma_filter[7] = -0.000472644; + luma_filter[8] = -0.000252236; + luma_filter[9] = 0.000198929; + luma_filter[10] = 0.000687058; + luma_filter[11] = 0.000944112; + luma_filter[12] = 0.000803467; + luma_filter[13] = 0.000363199; + luma_filter[14] = 0.000013422; + luma_filter[15] = 0.000253402; + luma_filter[16] = 0.001339461; + luma_filter[17] = 0.002932972; + luma_filter[18] = 0.003983485; + luma_filter[19] = 0.003026683; + luma_filter[20] = -0.001102056; + luma_filter[21] = -0.008373026; + luma_filter[22] = -0.016897700; + luma_filter[23] = -0.022914480; + luma_filter[24] = -0.021642347; + luma_filter[25] = -0.008863273; + luma_filter[26] = 0.017271957; + luma_filter[27] = 0.054921920; + luma_filter[28] = 0.098342579; + luma_filter[29] = 0.139044281; + luma_filter[30] = 0.168055832; + luma_filter[31] = 0.178571429; + + chroma_filter[0] = 0.001384762; + chroma_filter[1] = 0.001678312; + chroma_filter[2] = 0.002021715; + chroma_filter[3] = 0.002420562; + chroma_filter[4] = 0.002880460; + chroma_filter[5] = 0.003406879; + chroma_filter[6] = 0.004004985; + chroma_filter[7] = 0.004679445; + chroma_filter[8] = 0.005434218; + chroma_filter[9] = 0.006272332; + chroma_filter[10] = 0.007195654; + chroma_filter[11] = 0.008204665; + chroma_filter[12] = 0.009298238; + chroma_filter[13] = 0.010473450; + chroma_filter[14] = 0.011725413; + chroma_filter[15] = 0.013047155; + chroma_filter[16] = 0.014429548; + chroma_filter[17] = 0.015861306; + chroma_filter[18] = 0.017329037; + chroma_filter[19] = 0.018817382; + chroma_filter[20] = 0.020309220; + chroma_filter[21] = 0.021785952; + chroma_filter[22] = 0.023227857; + chroma_filter[23] = 0.024614500; + chroma_filter[24] = 0.025925203; + chroma_filter[25] = 0.027139546; + chroma_filter[26] = 0.028237893; + chroma_filter[27] = 0.029201910; + chroma_filter[28] = 0.030015081; + chroma_filter[29] = 0.030663170; + chroma_filter[30] = 0.031134640; + chroma_filter[31] = 0.031420995; + chroma_filter[32] = 0.031517031; + } + + else if (VHS_BleedMode == 4) { //Two-Phase (RetroArch) + luma_filter[0] = -0.000174844; + luma_filter[1] = -0.000205844; + luma_filter[2] = -0.000149453; + luma_filter[3] = -0.000051693; + luma_filter[4] = 0.000000000; + luma_filter[5] = -0.000066171; + luma_filter[6] = -0.000245058; + luma_filter[7] = -0.000432928; + luma_filter[8] = -0.000472644; + luma_filter[9] = -0.000252236; + luma_filter[10] = 0.000198929; + luma_filter[11] = 0.000687058; + luma_filter[12] = 0.000944112; + luma_filter[13] = 0.000803467; + luma_filter[14] = 0.000363199; + luma_filter[15] = 0.000013422; + luma_filter[16] = 0.000253402; + luma_filter[17] = 0.001339461; + luma_filter[18] = 0.002932972; + luma_filter[19] = 0.003983485; + luma_filter[20] = 0.003026683; + luma_filter[21] = -0.001102056; + luma_filter[22] = -0.008373026; + luma_filter[23] = -0.016897700; + luma_filter[24] = -0.022914480; + luma_filter[25] = -0.021642347; + luma_filter[26] = -0.008863273; + luma_filter[27] = 0.017271957; + luma_filter[28] = 0.054921920; + luma_filter[29] = 0.098342579; + luma_filter[30] = 0.139044281; + luma_filter[31] = 0.168055832; + luma_filter[32] = 0.178571429; + + chroma_filter[0] = 0.001384762; + chroma_filter[1] = 0.001678312; + chroma_filter[2] = 0.002021715; + chroma_filter[3] = 0.002420562; + chroma_filter[4] = 0.002880460; + chroma_filter[5] = 0.003406879; + chroma_filter[6] = 0.004004985; + chroma_filter[7] = 0.004679445; + chroma_filter[8] = 0.005434218; + chroma_filter[9] = 0.006272332; + chroma_filter[10] = 0.007195654; + chroma_filter[11] = 0.008204665; + chroma_filter[12] = 0.009298238; + chroma_filter[13] = 0.010473450; + chroma_filter[14] = 0.011725413; + chroma_filter[15] = 0.013047155; + chroma_filter[16] = 0.014429548; + chroma_filter[17] = 0.015861306; + chroma_filter[18] = 0.017329037; + chroma_filter[19] = 0.018817382; + chroma_filter[20] = 0.020309220; + chroma_filter[21] = 0.021785952; + chroma_filter[22] = 0.023227857; + chroma_filter[23] = 0.024614500; + chroma_filter[24] = 0.025925203; + chroma_filter[25] = 0.027139546; + chroma_filter[26] = 0.028237893; + chroma_filter[27] = 0.029201910; + chroma_filter[28] = 0.030015081; + chroma_filter[29] = 0.030663170; + chroma_filter[30] = 0.031134640; + chroma_filter[31] = 0.031420995; + chroma_filter[32] = 0.031517031; + } \ No newline at end of file