mirror of
https://github.com/libretro/slang-shaders.git
synced 2024-11-23 08:19:54 +00:00
add VHSPro ported from reshade
This commit is contained in:
parent
9a8b4a70fc
commit
1ea4c2f33d
38
vhs/VHSPro.slangp
Normal file
38
vhs/VHSPro.slangp
Normal file
@ -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
|
37
vhs/shaders/VHSPro/VHSPro_Clear.slang
Normal file
37
vhs/shaders/VHSPro/VHSPro_Clear.slang
Normal file
@ -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);
|
||||
}
|
282
vhs/shaders/VHSPro/VHSPro_First.slang
Normal file
282
vhs/shaders/VHSPro/VHSPro_First.slang
Normal file
@ -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;
|
||||
}
|
56
vhs/shaders/VHSPro/VHSPro_Forth.slang
Normal file
56
vhs/shaders/VHSPro/VHSPro_Forth.slang
Normal file
@ -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);
|
||||
}
|
49
vhs/shaders/VHSPro/VHSPro_LastFrame.slang
Normal file
49
vhs/shaders/VHSPro/VHSPro_LastFrame.slang
Normal file
@ -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);
|
||||
}
|
152
vhs/shaders/VHSPro/VHSPro_Second.slang
Normal file
152
vhs/shaders/VHSPro/VHSPro_Second.slang
Normal file
@ -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);
|
||||
}
|
68
vhs/shaders/VHSPro/VHSPro_Tape.slang
Normal file
68
vhs/shaders/VHSPro/VHSPro_Tape.slang
Normal file
@ -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);
|
||||
}
|
66
vhs/shaders/VHSPro/VHSPro_Third.slang
Normal file
66
vhs/shaders/VHSPro/VHSPro_Third.slang
Normal file
@ -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(diff<feedbackThresh) diff = 0.0;
|
||||
vec3 fbn = fc*diff*feedbackAmount; //feedback new
|
||||
// fbn = vec3(0.0, 0.0, 0.0);
|
||||
|
||||
//feedback buffer
|
||||
vec3 fbb = ( //blur old bufffer a bit
|
||||
texture( _FeedbackTex, texcoord).rgb +
|
||||
texture( _FeedbackTex, texcoord + vec2(one_x, 0.0)).rgb +
|
||||
texture( _FeedbackTex, texcoord - vec2(one_x, 0.0)).rgb
|
||||
) / 3.0;
|
||||
fbb *= feedbackFade;
|
||||
|
||||
//blend
|
||||
fc = bm_screen(fc, fbb);
|
||||
fbn = bm_screen(fbn, fbb); //feedback
|
||||
vec4 feedbackoutput = vec4(fc, 1.0);
|
||||
vec4 feedback = vec4(fbn * feedbackColor, 1.0);
|
||||
FragColor = feedback;
|
||||
}
|
21
vhs/shaders/VHSPro/VHSPro_constants.inc
Normal file
21
vhs/shaders/VHSPro/VHSPro_constants.inc
Normal file
@ -0,0 +1,21 @@
|
||||
//textures and samplers
|
||||
#ifndef screenLinesRes
|
||||
#define screenLinesRes 480.0 //Screen Resolution (to use in _TapeTex, has to be the same as screenLinesNum)
|
||||
#endif
|
||||
|
||||
#ifndef noiseLinesRes
|
||||
#define noiseLinesRes 480.0 //Vertical Resolution (to use in _TapeTex, has to be the same as noiseLinesNum)
|
||||
#endif
|
||||
|
||||
const float fisheyeSize = 1.2; //Size (DO NOT CHANGE)
|
||||
const float filmGrainPower = 1.0; //Film Grain Power (DO NOT CHANGE)
|
||||
const float feedbackAmp = 1.0; //Feedback Amp (DO NOT CHANGE)
|
||||
|
||||
#define _ScreenParams vec2(params.OutputSize.x, params.OutputSize.y)
|
||||
#undef PixelSize
|
||||
#define PixelSize vec2(params.OutputSize.z, params.OutputSize.w)
|
||||
|
||||
const float Pi2 = 6.283185307;
|
||||
|
||||
#define TEXHEIGHT int(noiseLinesRes)
|
||||
#define TEXWIDTH int((float(TEXHEIGHT)*float(params.OutputSize.x)/float(params.OutputSize.y)))
|
361
vhs/shaders/VHSPro/VHSPro_functions.inc
Normal file
361
vhs/shaders/VHSPro/VHSPro_functions.inc
Normal file
@ -0,0 +1,361 @@
|
||||
//functions
|
||||
|
||||
#define PI 3.14159265359
|
||||
const vec3 MOD3 = vec3(443.8975, 397.2973, 491.1871);
|
||||
|
||||
float fmod(float a, float b) {
|
||||
const float c = fract(abs(a / b)) * abs(b);
|
||||
if (a < 0)
|
||||
return -c;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
vec3 bms(vec3 c1, vec3 c2){ return 1.0- (1.0-c1)*(1.0-c2); }
|
||||
|
||||
float bms(float c1, float c2){ return 1.0- (1.0-c1)*(1.0-c2); }
|
||||
|
||||
//turns sth on and off //a - how often
|
||||
float onOff(float a, float b, float c, float t)
|
||||
{
|
||||
return step(c, sin(t + a*cos(t*b)));
|
||||
}
|
||||
|
||||
float hash( float n ){ return fract(sin(n)*43758.5453123); }
|
||||
|
||||
float hash12(vec2 p){
|
||||
vec3 p3 = fract(vec3(p.xyx) * MOD3);
|
||||
p3 += dot(p3, p3.yzx + 19.19);
|
||||
return fract(p3.x * p3.z * p3.y);
|
||||
}
|
||||
|
||||
vec2 hash22(vec2 p) {
|
||||
vec3 p3 = fract(vec3(p.xyx) * MOD3);
|
||||
p3 += dot(p3.zxy, p3.yzx+19.19);
|
||||
return fract(vec2((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y));
|
||||
}
|
||||
|
||||
//random hash
|
||||
vec4 hash42(vec2 p)
|
||||
{
|
||||
vec4 p4 = fract(vec4(p.xyxy) * vec4(443.8975,397.2973, 491.1871, 470.7827));
|
||||
p4 += dot(p4.wzxy, p4 + 19.19);
|
||||
return fract(vec4(p4.x * p4.y, p4.x*p4.z, p4.y*p4.w, p4.x*p4.w));
|
||||
}
|
||||
|
||||
float niq( in vec3 x ){
|
||||
const vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f*f*(3.0-2.0*f);
|
||||
const float n = p.x + p.y*57.0 + 113.0*p.z;
|
||||
return mix(mix( mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
|
||||
mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y),
|
||||
mix( mix( hash(n+113.0), hash(n+114.0),f.x),
|
||||
mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
|
||||
}
|
||||
|
||||
float filmGrain(vec2 uv, float t, float c )
|
||||
{
|
||||
//cheap noise - is ok atm
|
||||
return pow(hash12( uv + 0.07*fract( t ) ), 3);
|
||||
}
|
||||
|
||||
vec2 n4rand_bw( vec2 p, float t, float c )
|
||||
{
|
||||
t = fract( t );//that's why its sort of twitching
|
||||
vec2 nrnd0 = hash22( p + 0.07*t );
|
||||
c = 1.0 / (10.0*c); //iMouse.y / iResolution.y
|
||||
return pow(nrnd0, vec2(c,c)); //TODO try to invert 1-...
|
||||
}
|
||||
|
||||
float scanLines(vec2 p, float t)
|
||||
{
|
||||
|
||||
//cheap (maybe make an option later)
|
||||
// float scanLineWidth = 0.26;
|
||||
// float scans = 0.5*(cos((p.y*screenLinesNum+t+.5)*2.0*PI) + 1.0);
|
||||
// if(scans>scanLineWidth) 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.y<oy*ln && uv.y>oy*(ln-w)) ////if(uv.y>oy*ln && uv.y<oy*(ln+w))
|
||||
// uv.y = floor( uv.y*slb +sh2 +sh )/slb - (sh2-1.)/slb - sh/slb;
|
||||
|
||||
// #else
|
||||
|
||||
if(uv.y<oy*ln && uv.y>oy*(ln-w)) ////if(uv.y>oy*ln && uv.y<oy*(ln+w))
|
||||
uv.y = floor( uv.y*slb +sh2 )/slb - (sh2-1.0)/slb ;
|
||||
|
||||
// #endif
|
||||
|
||||
return uv;
|
||||
}
|
||||
|
||||
float rnd_rd(vec2 co)
|
||||
{
|
||||
return fract(sin(fmod(dot(co.xy ,vec2(12.9898,78.233)),3.14)) * 43758.5453);
|
||||
}
|
||||
|
||||
//DANG WINDOWS
|
||||
vec3 rgb2yiq(vec3 c)
|
||||
{
|
||||
return vec3(
|
||||
0.2989*c.x + 0.5959*c.y + 0.2115*c.z,
|
||||
0.5870*c.x - 0.2744*c.y - 0.5229*c.z,
|
||||
0.1140*c.x - 0.3216*c.y + 0.3114*c.z);
|
||||
}
|
||||
|
||||
vec3 yiq2rgb(vec3 c)
|
||||
{
|
||||
return vec3(
|
||||
1.0*c.x +1.0*c.y +1.0*c.z,
|
||||
0.956*c.x - 0.2720*c.y - 1.1060*c.z,
|
||||
0.6210*c.x - 0.6474*c.y + 1.7046*c.z);
|
||||
}
|
||||
|
||||
//rgb distortion
|
||||
vec3 rgbDistortion(vec2 uv, float magnitude, float t)
|
||||
{
|
||||
magnitude *= 0.0001; // float magnitude = 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)))*magnitude;
|
||||
offsetX.g += rnd_rd(vec2(t*0.004,uv.y*0.002)) * 0.004 + sin(t*9.0)*magnitude;
|
||||
// offsetX.b = uv.y + rnd_rd(vec2(cos(t*0.01),sin(uv.y)))*magnitude;
|
||||
// offsetX.b = uv.y + rand_rd(vec2(cos(t*0.01),sin(uv.y)))*magnitude;
|
||||
|
||||
vec3 col = vec3(0.0, 0.0, 0.0);
|
||||
//it cud be optimized / but hm
|
||||
col.x = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.r, uv.y) ).rgb ).x;
|
||||
col.y = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.g, uv.y) ).rgb ).y;
|
||||
col.z = rgb2yiq( texture( SamplerColorVHS, vec2(offsetX.b, uv.y) ).rgb ).z;
|
||||
|
||||
col = yiq2rgb(col);
|
||||
return col;
|
||||
}
|
||||
|
||||
float rndln(vec2 p, float t)
|
||||
{
|
||||
float sample_ln = rnd_rd(vec2(1.0,2.0*cos(t))*t*8.0 + p*1.0).x;
|
||||
sample_ln *= sample_ln;//*sample;
|
||||
return sample_ln;
|
||||
}
|
||||
|
||||
float lineNoise(vec2 p, float t)
|
||||
{
|
||||
float n = rndln(p* vec2(0.5,1.0) + vec2(1.0,3.0), t)*20.0;
|
||||
|
||||
float freq = abs(sin(t)); //1.
|
||||
float c = n*smoothstep(fmod(p.y*4.0 + t/2.0+sin(t + sin(t*0.63)),freq), 0.0,0.95);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
// 3d noise function (iq's)
|
||||
float n( in vec3 x )
|
||||
{
|
||||
const vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
f = f*f*(3.0-2.0*f);
|
||||
const float n = p.x + p.y*57.0 + 113.0*p.z;
|
||||
return mix(mix(mix( hash(n+0.0), hash(n+1.0),f.x),
|
||||
mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y),
|
||||
mix( mix( hash(n+113.0), hash(n+114.0),f.x),
|
||||
mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
|
||||
}
|
||||
|
||||
float tapeNoiseLines(vec2 p, float t){
|
||||
|
||||
//so atm line noise is depending on hash for int values
|
||||
//i gotta rewrite to for hash for 0..1 values
|
||||
//then i can use normilized p for generating lines
|
||||
|
||||
const float y = p.y*_ScreenParams.y;
|
||||
const float s = t*2.0;
|
||||
return (niq( vec3(y*0.01 +s, 1.0, 1.0) ) + 0.0)
|
||||
*(niq( vec3(y*0.011+1000.0+s, 1.0, 1.0) ) + 0.0)
|
||||
*(niq( vec3(y*0.51+421.0+s, 1.0, 1.0) ) + 0.0)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
float tapeNoise(float nl, vec2 p, float t){
|
||||
|
||||
//TODO custom adjustable density (Probability distribution)
|
||||
// but will be expensive (atm its ok)
|
||||
|
||||
//atm its just contrast noise
|
||||
|
||||
//this generates noise mask
|
||||
float nm = hash12( fract(p+t*vec2(0.234,0.637)) )
|
||||
// *hash12( fract(p+t*vec2(0.123,0.867)) )
|
||||
// *hash12( fract(p+t*vec2(0.441,0.23)) );
|
||||
;
|
||||
nm = pow(nm, 4) +0.3; //cheap and ok
|
||||
//nm += 0.3 ; //just bit brighter or just more to threshold?
|
||||
|
||||
nl*= nm; // put mask
|
||||
// nl += 0.3; //Value add .3//
|
||||
|
||||
if(nl<tapeNoiseTH) nl = 0.0; else nl =1.0; //threshold
|
||||
return nl;
|
||||
}
|
||||
|
||||
vec2 twitchVertical(float freq, vec2 uv, float t){
|
||||
|
||||
float vShift = 0.4*onOff(freq,3.0,0.9, t);
|
||||
vShift*=(sin(t)*sin(t*20.0) + (0.5 + 0.1*sin(t*200.0)*cos(t)));
|
||||
uv.y = fmod(uv.y + vShift, 1.0);
|
||||
return uv;
|
||||
}
|
||||
|
||||
vec2 twitchHorizonal(float freq, vec2 uv, float t){
|
||||
|
||||
uv.x += sin(uv.y*10.0 + t)/250.0*onOff(freq,4.0,0.3, t)*(1.0+cos(t*80.0))*(1.0/(1.0+20.0*(uv.y-fmod(t/4.0,1.0))*(uv.y-fmod(t/4.0, 1.0))));
|
||||
return uv;
|
||||
}
|
||||
|
||||
|
||||
//all that shit is for postVHS"Pro"_First - end
|
||||
|
||||
//all that shit is for postVHS"Pro"_Second
|
||||
|
||||
//size 1.2, bend 2.
|
||||
vec2 fishEye(vec2 uv, float size, float bend)
|
||||
{
|
||||
if (!VHS_FishEye_Hyperspace){
|
||||
uv -= vec2(0.5,0.5);
|
||||
uv *= size*(1.0/size+bend*uv.x*uv.x*uv.y*uv.y);
|
||||
uv += vec2(0.5,0.5);
|
||||
}
|
||||
|
||||
if (VHS_FishEye_Hyperspace){
|
||||
|
||||
//http://paulbourke.net/miscellaneous/lenscorrection/
|
||||
|
||||
const float prop = _ScreenParams.x / _ScreenParams.y;
|
||||
const vec2 m = vec2(0.5, 0.5 / prop);
|
||||
const vec2 d = (uv*_ScreenParams.xy) /_ScreenParams.x - m;
|
||||
const float r = sqrt(dot(d, d));
|
||||
float bind;
|
||||
|
||||
float power = ( 2.0 * 3.141592 / (2.0 * sqrt(dot(m, m))) ) *
|
||||
(bend/50.0 - 0.5); //amount of effect
|
||||
|
||||
if (power > 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); }
|
246
vhs/shaders/VHSPro/VHSPro_params.inc
Normal file
246
vhs/shaders/VHSPro/VHSPro_params.inc
Normal file
@ -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."
|
42
vhs/shaders/VHSPro/feedback.slang
Normal file
42
vhs/shaders/VHSPro/feedback.slang
Normal file
@ -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));
|
||||
}
|
318
vhs/shaders/VHSPro/taps.inc
Normal file
318
vhs/shaders/VHSPro/taps.inc
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user