From cc988bdeb59826df4a07562e1ea97e2128464d62 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Tue, 27 Sep 2022 10:17:59 -0500 Subject: [PATCH] Create analog_overshoot.slang --- ntsc/shaders/analog_overshoot.slang | 105 ++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 ntsc/shaders/analog_overshoot.slang diff --git a/ntsc/shaders/analog_overshoot.slang b/ntsc/shaders/analog_overshoot.slang new file mode 100644 index 0000000..f96f055 --- /dev/null +++ b/ntsc/shaders/analog_overshoot.slang @@ -0,0 +1,105 @@ +#version 450 + +// Analog Overshoot +// by Astherix + +// adapted for slang from NTSC Codec (w/Overshoot & Noise) shadertoy +// https://www.shadertoy.com/view/flG3zd + +// Licensed LGPLv3 + +// This pass applies a simulation of analog overshoot, which +// is the cause for ghosting artifacts around edges (sharp transitions) +// This is not necessary for encoding/decoding. + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OriginalSize; + vec4 OutputSize; + uint FrameCount; + float hermite_tension, hermite_bias, decode_chroma_luma_separately; +} params; + +// These two define the tension and bias parameters +// of the Hermite interpolation function +// Values closer to 0.5 on both parameters yield +// more aggressive ghosting artifacts +#pragma parameter hermite_tension "Hermite Tension" 0.25 0.01 1.0 0.01 +#pragma parameter hermite_bias "Hermite Bias" 0.75 0.01 1.0 0.01 + +#pragma parameter decode_chroma_luma_separately "Decode Chroma and Luma Separately" 1.0 0.0 1.0 1.0 +#define DECODE_CHROMA_LUMA_SEPARATELY params.decode_chroma_luma_separately + +#define HERMITE_TENSION params.hermite_tension +#define HERMITE_BIAS params.hermite_bias + +#define iChannel0 Source +#define iResolution params.OutputSize.xy +#define fragCoord (vTexCoord.xy * params.OutputSize.xy) +#define fragColor FragColor +#define iFrame params.FrameCount +#define iTime (params.FrameCount / 60) + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} 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 * 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; + +float hermite(float y0, float y1, float y2, float y3, float m, float tension, float bias) { + float m2 = m*m, + m3 = m2*m, + m0 = (y1-y0)*(1.0+bias)*(1.0-tension)/2.0; + m0 = m0 + (y2-y1)*(1.0-bias)*(1.0-tension)/2.0; + float m1 = (y2-y1)*(1.0+bias)*(1.0-tension)/2.0; + m1 = m1 + (y3-y2)*(1.0-bias)*(1.0-tension)/2.0; + float a0 = 2.0*m3 - 3.0*m2 + 1.0, + a1 = m3 - 2.0*m2 + m, + a2 = m3 - m2, + a3 = -2.0*m3 + 3.0*m2; + + return (a0*y1+a1*m0+a2*m1+a3*y2); +} + +void main() +{ + vec2 px = vTexCoord.xy * params.OutputSize.zw; + // Normalized pixel coordinates (from 0 to 1) + vec2 fcm1 = vec2(fragCoord.x-4.0, fragCoord.y)/iResolution.xy, + fcm0 = vec2(fragCoord.x-0.0, fragCoord.y)/iResolution.xy, + fcp1 = vec2(fragCoord.x+4.0, fragCoord.y)/iResolution.xy, + fcp2 = vec2(fragCoord.x+8.0, fragCoord.y)/iResolution.xy; + + vec3 y0 = texture(Source, fcm1).xyz, + y1 = texture(Source, fcm0).xyz, + y2 = texture(Source, fcp1).xyz, + y3 = texture(Source, fcp2).xyz; + + vec3 o = y1; + + float l = HERMITE_TENSION, y = HERMITE_BIAS; + + vec3 f = vec3( + hermite(y0.x, y1.x, y2.x, y3.x, l, y, y * 50.0), + hermite(y0.y, y1.y, y2.y, y3.y, l, y, y * 50.0), + hermite(y0.z, y1.z, y2.z, y3.z, l, y, y * 50.0) + ); + + fragColor = mix(vec4(f, 1.0), vec4(y1, 1.0), DECODE_CHROMA_LUMA_SEPARATELY); +}