mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-25 00:51:29 +11:00
152 lines
4 KiB
Plaintext
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);
|
|
} |