slang-shaders/vhs/shaders/VHSPro/VHSPro_Second.slang
2020-06-19 16:19:28 -05:00

152 lines
4 KiB
Plaintext

#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);
}