mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-21 23:31:30 +11:00
port ntsc-simple to slang (#471)
* Update and rename ntsc-feather.slangp to ntsc-simple.slangp * Update and rename ntsc-feather.slang to ntsc-simple.slang
This commit is contained in:
parent
eef1782313
commit
b3145db598
|
@ -1,6 +0,0 @@
|
|||
shaders = 1
|
||||
shader0 = shaders/ntsc-simple/ntsc-feather.slang
|
||||
filter_linear0 = true
|
||||
|
||||
|
||||
|
7
ntsc/ntsc-simple.slangp
Normal file
7
ntsc/ntsc-simple.slangp
Normal file
|
@ -0,0 +1,7 @@
|
|||
shaders = 1
|
||||
shader0 = shaders/ntsc-simple/ntsc-simple.slang
|
||||
filter_linear0 = "false"
|
||||
scale_type_x0 = "source"
|
||||
scale_x0 = "1.000000"
|
||||
scale_type_y0 = "source"
|
||||
scale_y0 = "1.000000"
|
|
@ -1,146 +0,0 @@
|
|||
#version 450
|
||||
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
float MASK;
|
||||
float COMPOSITE_LOWPASS;
|
||||
float COL_BLEED;
|
||||
float NTSC_COL;
|
||||
|
||||
} params;
|
||||
|
||||
|
||||
#pragma parameter MASK "Color Subcarrier Artifacts" 0.08 0.0 1.0 0.01
|
||||
#pragma parameter COMPOSITE_LOWPASS "Composite Lowpass" 0.8 0.0 2.0 0.05
|
||||
#pragma parameter COL_BLEED "Chroma Bleed" 1.4 0.0 2.0 0.05
|
||||
#pragma parameter NTSC_COL "NTSC Colors " 0.0 0.0 1.0 1.0
|
||||
|
||||
#define MASK params.MASK
|
||||
#define COMPOSITE_LOWPASS params.COMPOSITE_LOWPASS
|
||||
#define COL_BLEED params.COL_BLEED
|
||||
#define NTSC_COL params.NTSC_COL
|
||||
#define PI 3.141592
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
vec4 OutputSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 SourceSize;
|
||||
uint FrameCount;
|
||||
|
||||
} global;
|
||||
|
||||
|
||||
#define OutputSize global.OutputSize
|
||||
#define SourceSize global.SourceSize
|
||||
#define OriginalSize global.OriginalSize
|
||||
#define FrameCount global.FrameCount
|
||||
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord * 1.0001;
|
||||
}
|
||||
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
|
||||
|
||||
mat3 RGBtoYIQ = mat3(
|
||||
0.2989, 0.5870, 0.1140,
|
||||
0.5959, -0.2744, -0.3216,
|
||||
0.2115, -0.5229, 0.3114);
|
||||
|
||||
mat3 YIQtoRGB = mat3(
|
||||
1.0, 0.956, 0.6210,
|
||||
1.0, -0.2720, -0.6474,
|
||||
1.0, -1.1060, 1.7046);
|
||||
|
||||
const mat3 NTSC = mat3(
|
||||
1.8088923, -0.6480268, -0.0833558,
|
||||
0.4062922 , 0.6175271, -0.0038849,
|
||||
-0.0025872, -0.103848 , 1.182318);
|
||||
|
||||
#define Time sin(float(FrameCount))
|
||||
|
||||
float phase = OriginalSize.x<300.0 ? 4.0*PI/15.0 : PI/3.0;
|
||||
#define SC MASK*sin(vTexCoord.x*SourceSize.x*phase)+1.0-MASK
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
vec2 cent = floor(vTexCoord*SourceSize.xy)+0.5;
|
||||
vec2 coords = cent*SourceSize.zw;
|
||||
coords = vec2(mix(vTexCoord.x,coords.x,0.2),coords.y);
|
||||
|
||||
vec3 res = texture(Source,coords).rgb; res *= RGBtoYIQ;
|
||||
float onetexel = SourceSize.z*COMPOSITE_LOWPASS;
|
||||
float bleed = SourceSize.z*COL_BLEED;
|
||||
vec3 resr = texture(Source,coords-(vec2(2.0*bleed,0.0))).rgb; resr *= RGBtoYIQ;
|
||||
vec3 resru = texture(Source,coords-(vec2(onetexel,0.0))).rgb; resru *= RGBtoYIQ;
|
||||
vec3 resrr = texture(Source,coords-(vec2(3.0*bleed,0.0))).rgb; resrr *= RGBtoYIQ;
|
||||
|
||||
vec3 resl = texture(Source,coords+(vec2(2.0*bleed,0.0))).rgb; resl *= RGBtoYIQ;
|
||||
vec3 reslu = texture(Source,coords+(vec2(bleed,0.0))).rgb; reslu *= RGBtoYIQ;
|
||||
vec3 resll = texture(Source,coords+(vec2(3.0*bleed,0.0))).rgb; resll *= RGBtoYIQ;
|
||||
|
||||
//color bleed
|
||||
res.gb += (resr.gb+resl.gb+resrr.gb+resll.gb+reslu.gb+resru.gb); res.gb /= 7.0;
|
||||
//overall bluriness
|
||||
res.r = (res.r + resru.r)/2.0;
|
||||
|
||||
vec3 checker = texture(Source,vTexCoord - vec2(0.25/OriginalSize.x,0.0)).rgb; checker *= RGBtoYIQ;
|
||||
vec3 checkerl = texture(Source,vTexCoord + vec2(0.1/OriginalSize.x,0.0)).rgb; checkerl *= RGBtoYIQ;
|
||||
|
||||
float diff = res.g-checker.g;
|
||||
float diffl = res.g-checkerl.g;
|
||||
float ydiff = res.r-checker.r;
|
||||
float ydiffl = res.r-checkerl.r;
|
||||
|
||||
float x = mod(floor(vTexCoord.x*SourceSize.x),2.0);
|
||||
float y = mod(floor(vTexCoord.y*SourceSize.y),2.0);
|
||||
|
||||
|
||||
//Color subcarrier pattern
|
||||
if (y == 0.0 && x == 0.0 && Time < 0.0 && diff > 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && diff > 0.0)
|
||||
|
||||
res.b *= SC; // ok
|
||||
|
||||
else if (y == 1.0 && x == 1.0 && Time < 0.0 && diff > 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && diff > 0.0)
|
||||
|
||||
res.b *= SC; // ok
|
||||
|
||||
else if (y == 0.0 && x == 0.0 && Time < 0.0 && ydiff < 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && ydiff < 0.0)
|
||||
|
||||
res.r *= SC; // ok
|
||||
|
||||
else if (y == 1.0 && x == 1.0 && Time < 0.0 && ydiff < 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && ydiff < 0.0)
|
||||
res.r *= SC; // ok
|
||||
|
||||
else if (y == 0.0 && x == 0.0 && Time < 0.0 && ydiffl < 0.0 || y == 0.0 && x == 1.0 && Time > 0.0 && ydiffl < 0.0)
|
||||
|
||||
res.r *= SC;
|
||||
|
||||
else if (y == 1.0 && x == 1.0 && Time < 0.0 && ydiffl < 0.0 || y == 1.0 && x == 0.0 && Time > 0.0 && ydiffl < 0.0)
|
||||
res.r *= SC;
|
||||
|
||||
//for testing
|
||||
//if (ydiffl < 0.0) res = vec3(0.0);
|
||||
|
||||
///
|
||||
res *= YIQtoRGB;
|
||||
if (NTSC_COL == 1.0)res *= NTSC;
|
||||
FragColor = vec4(res,1.0);
|
||||
}
|
146
ntsc/shaders/ntsc-simple/ntsc-simple.slang
Normal file
146
ntsc/shaders/ntsc-simple/ntsc-simple.slang
Normal file
|
@ -0,0 +1,146 @@
|
|||
#version 450
|
||||
/*
|
||||
Simple S-video like shader by DariusG 2023
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
any later version.
|
||||
*/
|
||||
|
||||
layout(push_constant) uniform Push
|
||||
{
|
||||
float CHR_BLUR, L_BLUR, CHROMA_SATURATION, BRIGHTNESS, IHUE, QHUE;
|
||||
} params;
|
||||
|
||||
|
||||
|
||||
#pragma parameter CHR_BLUR "CHROMA RESOLUTION" 4.0 1.0 10.0 0.1
|
||||
#pragma parameter L_BLUR "LUMA RESOLUTION" 8.0 2.0 10.0 0.25
|
||||
#pragma parameter CHROMA_SATURATION "CHROMA SATURATION" 5.0 0.0 15.0 0.1
|
||||
#pragma parameter BRIGHTNESS "LUMA BRIGHTNESS" 0.55 0.0 2.0 0.01
|
||||
#pragma parameter IHUE "I SHIFT (blue to orange)" 0.0 -1.0 1.0 0.01
|
||||
#pragma parameter QHUE "Q SHIFT (green to purple)" 0.0 -1.0 1.0 0.01
|
||||
|
||||
|
||||
|
||||
#define CHR_BLUR params.CHR_BLUR
|
||||
#define L_BLUR params.L_BLUR
|
||||
#define CHROMA_SATURATION params.CHROMA_SATURATION
|
||||
#define BRIGHTNESS params.BRIGHTNESS
|
||||
#define IHUE params.IHUE
|
||||
#define QHUE params.QHUE
|
||||
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO
|
||||
{
|
||||
mat4 MVP;
|
||||
vec4 OutputSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 SourceSize;
|
||||
uint FrameCount;
|
||||
|
||||
} global;
|
||||
|
||||
|
||||
#define OutputSize global.OutputSize
|
||||
#define SourceSize global.SourceSize
|
||||
#define OriginalSize global.OriginalSize
|
||||
#define FrameCount global.FrameCount
|
||||
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord * 1.0001;
|
||||
}
|
||||
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
#define TAU 6.28318530717958647693
|
||||
#define FSC 3.57945*4.0
|
||||
|
||||
// Size of the decoding FIR filter
|
||||
#define FIR_SIZE 20
|
||||
|
||||
// YIQ to RGB matrices
|
||||
const mat3 yiq_to_rgb = mat3(1.000, 1.000, 1.000,
|
||||
0.956,-0.272,-1.106,
|
||||
0.621,-0.647, 1.703);
|
||||
|
||||
const mat3 rgb_to_yiq = mat3(0.299, 0.596, 0.211,
|
||||
0.587,-0.274,-0.523,
|
||||
0.114,-0.322, 0.312);
|
||||
|
||||
float blackman(float n, float N) {
|
||||
float a0 = (1.0 - 0.16) / 2.0;
|
||||
float a1 = 1.0 / 2.0;
|
||||
float a2 = 0.16 / 2.0;
|
||||
|
||||
return a0 - (a1 * cos((2.0 * PI * n) / N)) + (a2 * cos((4.0 * PI * n) / N));
|
||||
}
|
||||
|
||||
void main() {
|
||||
// moved due to GLES fix.
|
||||
mat3 mix_mat = mat3(
|
||||
1.0, 0.0, 0.0,
|
||||
IHUE, 1.0, 0.0,
|
||||
QHUE, 0.0, 1.0
|
||||
);
|
||||
|
||||
// Chroma decoder oscillator frequency
|
||||
float fc = SourceSize.x*TAU;
|
||||
|
||||
float counter = 0.0;
|
||||
vec3 yiq = vec3(0.0);
|
||||
|
||||
for (int d = -FIR_SIZE; d < FIR_SIZE; d++) {
|
||||
|
||||
// LUMA encode
|
||||
vec2 pos = vec2((vTexCoord.x + (float(d)/2.0/L_BLUR)*SourceSize.z), vTexCoord.y);
|
||||
vec3 s = texture(Source, pos).rgb;
|
||||
s = rgb_to_yiq*s;
|
||||
// LUMA encode end
|
||||
|
||||
// LUMA decode
|
||||
// Apply Blackman window for smoother colors
|
||||
float window = blackman(float(d/2 + 5), float(FIR_SIZE/2));
|
||||
yiq.r += s.r * BRIGHTNESS * window;
|
||||
// LUMA decode end!
|
||||
|
||||
// CHROMA encode
|
||||
pos = vec2(vTexCoord.x + (float(d)/CHR_BLUR)*SourceSize.z, vTexCoord.y);
|
||||
s = texture(Source, pos).rgb;
|
||||
s = rgb_to_yiq*s;
|
||||
s.yz *= vec2(cos(fc*vTexCoord.x+11.0*PI/60.0),sin(fc*vTexCoord.x+11.0*PI/60.0));
|
||||
// CHROMA encode end
|
||||
|
||||
// CHROMA decode
|
||||
// Apply Blackman window for smoother colors
|
||||
window = blackman(float(d + FIR_SIZE), float(FIR_SIZE * 2 + 1));
|
||||
float wt = fc * (vTexCoord.x - float(d)*SourceSize.z);
|
||||
yiq.yz += s.yz * vec2(cos(wt+11.0*PI/60.0), sin(wt+11.0*PI/60.0)) * window;
|
||||
// CHROMA decode end!
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
yiq.yz /= counter;
|
||||
yiq.r /= counter/4.0;
|
||||
|
||||
// Saturate chroma (IQ)
|
||||
yiq.yz *= CHROMA_SATURATION;
|
||||
// Control CHROMA Hue
|
||||
yiq *= mix_mat;
|
||||
// return to RGB
|
||||
FragColor = vec4((yiq_to_rgb * yiq), 1.0);
|
||||
}
|
Loading…
Reference in a new issue