1// VHS shader
2// by hunterk
3// adapted from ompuco's more AVdistortion shadertoy:
4// https://www.shadertoy.com/view/XlsczN
5
6// Parameter lines go here:
7#pragma parameter wiggle "Wiggle" 0.0 0.0 10.0 1.0
8#pragma parameter smear "Chroma Smear" 0.2 0.0 1.0 0.05
9
10#if defined(VERTEX)
11
12#if __VERSION__ >= 130
13#define COMPAT_VARYING out
14#define COMPAT_ATTRIBUTE in
15#define COMPAT_TEXTURE texture
16#else
17#define COMPAT_VARYING varying
18#define COMPAT_ATTRIBUTE attribute
19#define COMPAT_TEXTURE texture2D
20#endif
21
22#ifdef GL_ES
23#define COMPAT_PRECISION mediump
24#else
25#define COMPAT_PRECISION
26#endif
27
28COMPAT_ATTRIBUTE vec4 VertexCoord;
29COMPAT_ATTRIBUTE vec4 COLOR;
30COMPAT_ATTRIBUTE vec4 TexCoord;
31COMPAT_VARYING vec4 COL0;
32COMPAT_VARYING vec4 TEX0;
33
34vec4 _oPosition1;
35uniform mat4 MVPMatrix;
36uniform COMPAT_PRECISION int FrameDirection;
37uniform COMPAT_PRECISION int FrameCount;
38uniform COMPAT_PRECISION vec2 OutputSize;
39uniform COMPAT_PRECISION vec2 TextureSize;
40uniform COMPAT_PRECISION vec2 InputSize;
41
42// compatibility #defines
43#define vTexCoord TEX0.xy
44#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
45#define OutSize vec4(OutputSize, 1.0 / OutputSize)
46
47void main()
48{
49    gl_Position = MVPMatrix * VertexCoord;
50    TEX0.xy = TexCoord.xy;
51}
52
53#elif defined(FRAGMENT)
54
55#ifdef GL_ES
56#ifdef GL_FRAGMENT_PRECISION_HIGH
57precision highp float;
58#else
59precision mediump float;
60#endif
61#define COMPAT_PRECISION mediump
62#else
63#define COMPAT_PRECISION
64#endif
65
66#if __VERSION__ >= 130
67#define COMPAT_VARYING in
68#define COMPAT_TEXTURE texture
69out COMPAT_PRECISION vec4 FragColor;
70#else
71#define COMPAT_VARYING varying
72#define FragColor gl_FragColor
73#define COMPAT_TEXTURE texture2D
74#endif
75
76uniform COMPAT_PRECISION int FrameDirection;
77uniform COMPAT_PRECISION int FrameCount;
78uniform COMPAT_PRECISION vec2 OutputSize;
79uniform COMPAT_PRECISION vec2 TextureSize;
80uniform COMPAT_PRECISION vec2 InputSize;
81uniform sampler2D Texture;
82uniform sampler2D play;
83COMPAT_VARYING vec4 TEX0;
84
85// compatibility #defines
86#define Source Texture
87#define vTexCoord TEX0.xy
88
89#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
90#define OutSize vec4(OutputSize, 1.0 / OutputSize)
91
92#ifdef PARAMETER_UNIFORM
93uniform COMPAT_PRECISION float wiggle;
94uniform COMPAT_PRECISION float smear;
95#else
96#define wiggle 3.0
97#define smear 1.0
98#endif
99
100#define iTime mod(float(FrameCount), 7.0)
101#define iChannel0 Texture
102
103//YIQ/RGB shit
104vec3 rgb2yiq(vec3 c){
105					return vec3(
106						(0.2989*c.x + 0.5959*c.y + 0.2115*c.z),
107						(0.5870*c.x - 0.2744*c.y - 0.5229*c.z),
108						(0.1140*c.x - 0.3216*c.y + 0.3114*c.z)
109					);
110				}
111
112vec3 yiq2rgb(vec3 c){
113					return vec3(
114						(	 1.0*c.x +	  1.0*c.y + 	1.0*c.z),
115						( 0.956*c.x - 0.2720*c.y - 1.1060*c.z),
116						(0.6210*c.x - 0.6474*c.y + 1.7046*c.z)
117					);
118				}
119
120vec2 Circle(float Start, float Points, float Point)
121{
122	float Rad = (3.141592 * 2.0 * (1.0 / Points)) * (Point + Start);
123	//return vec2(sin(Rad), cos(Rad));
124		return vec2(-(.3+Rad), cos(Rad));
125
126}
127
128vec3 Blur(vec2 uv, float d){
129	float t = (sin(iTime*5.0+uv.y*5.0))/10.0;
130    float b = 1.0;
131    t=0.0;
132    vec2 PixelOffset=vec2(d+.0005*t,0);
133
134    float Start = 2.0 / 14.0;
135    vec2 Scale = 0.66 * 4.0 * 2.0 * PixelOffset.xy;
136
137    vec3 N0 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 0.0) * Scale).rgb;
138    vec3 N1 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 1.0) * Scale).rgb;
139    vec3 N2 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 2.0) * Scale).rgb;
140    vec3 N3 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 3.0) * Scale).rgb;
141    vec3 N4 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 4.0) * Scale).rgb;
142    vec3 N5 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 5.0) * Scale).rgb;
143    vec3 N6 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 6.0) * Scale).rgb;
144    vec3 N7 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 7.0) * Scale).rgb;
145    vec3 N8 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 8.0) * Scale).rgb;
146    vec3 N9 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 9.0) * Scale).rgb;
147    vec3 N10 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 10.0) * Scale).rgb;
148    vec3 N11 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 11.0) * Scale).rgb;
149    vec3 N12 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 12.0) * Scale).rgb;
150    vec3 N13 = COMPAT_TEXTURE(iChannel0, uv + Circle(Start, 14.0, 13.0) * Scale).rgb;
151    vec3 N14 = COMPAT_TEXTURE(iChannel0, uv).rgb;
152
153	vec4 clr = texture(iChannel0, uv);
154    float W = 1.0 / 15.0;
155
156    clr.rgb=
157		(N0 * W) +
158		(N1 * W) +
159		(N2 * W) +
160		(N3 * W) +
161		(N4 * W) +
162		(N5 * W) +
163		(N6 * W) +
164		(N7 * W) +
165		(N8 * W) +
166		(N9 * W) +
167		(N10 * W) +
168		(N11 * W) +
169		(N12 * W) +
170		(N13 * W) +
171		(N14 * W);
172    return  vec3(clr.xyz)*b;
173}
174
175float onOff(float a, float b, float c, float framecount)
176{
177	return step(c, sin((framecount * 0.001) + a*cos((framecount * 0.001)*b)));
178}
179
180vec2 jumpy(vec2 uv, float framecount)
181{
182	vec2 look = uv;
183	float window = 1./(1.+80.*(look.y-mod(framecount/4.,1.))*(look.y-mod(framecount/4.,1.)));
184	look.x += 0.05 * sin(look.y*10. + framecount)/20.*onOff(4.,4.,.3, framecount)*(0.5+cos(framecount*20.))*window;
185	float vShift = (0.1*wiggle) * 0.4*onOff(2.,3.,.9, framecount)*(sin(framecount)*sin(framecount*20.) +
186										 (0.5 + 0.1*sin(framecount*200.)*cos(framecount)));
187	look.y = mod(look.y - 0.01 * vShift, 1.);
188	return look;
189}
190
191void main()
192{
193	float d=.1-round(mod(iTime/3.0,1.0))*.1;
194	vec2 uv = jumpy(vTexCoord.xy, iTime);
195	vec2 uv2 = uv;
196
197    float s = 0.0001 * -d + 0.0001 * wiggle * sin(iTime);
198
199	float e = min(.30,pow(max(0.0,cos(uv.y*4.0+.3)-.75)*(s+0.5)*1.0,3.0))*25.0;
200    float r = (iTime*(2.0*s));
201    uv.x+=abs(r*pow(min(.003,(-uv.y+(.01*mod(iTime, 17.0))))*3.0,2.0));
202
203    d=.051+abs(sin(s/4.0));
204    float c = max(0.0001,.002*d) * smear;
205	vec2 uvo = uv;
206    vec4 final;
207	final.xyz =Blur(uv,c+c*(uv.x));
208    float y = rgb2yiq(final.xyz).r;
209
210	uv.x+=.01*d;
211    c*=6.0;
212    final.xyz =Blur(uv,c);
213    float i = rgb2yiq(final.xyz).g;
214
215    uv.x+=.005*d;
216
217    c*=2.50;
218    final.xyz =Blur(uv,c);
219    float q = rgb2yiq(final.xyz).b;
220	final = vec4(yiq2rgb(vec3(y,i,q))-pow(s+e*2.0,3.0), 1.0);
221
222	vec4 play_osd = COMPAT_TEXTURE(play, uv2 * TextureSize.xy / InputSize.xy);
223	float show_overlay = (mod(float(FrameCount), 100.0) < 50.0) && (float(FrameCount) < 500.0) ? play_osd.a : 0.0;
224	show_overlay = clamp(show_overlay, 0.0, 1.0);
225	final = mix(final, play_osd, show_overlay);
226
227    FragColor = final;
228}
229#endif
230