1#version 120
2// Compatibility #ifdefs needed for parameters
3#ifdef GL_ES
4#define COMPAT_PRECISION mediump
5#else
6#define COMPAT_PRECISION
7#endif
8
9// Parameter lines go here:
10#pragma parameter RETRO_PIXEL_SIZE "Retro Pixel Size" 0.84 0.0 1.0 0.01
11#ifdef PARAMETER_UNIFORM
12// All parameter floats need to have COMPAT_PRECISION in front of them
13uniform COMPAT_PRECISION float RETRO_PIXEL_SIZE;
14#else
15#define RETRO_PIXEL_SIZE 0.84
16#endif
17
18#if defined(VERTEX)
19
20#if __VERSION__ >= 130
21#define COMPAT_VARYING out
22#define COMPAT_ATTRIBUTE in
23#define COMPAT_TEXTURE texture
24#else
25#define COMPAT_VARYING varying
26#define COMPAT_ATTRIBUTE attribute
27#define COMPAT_TEXTURE texture2D
28#endif
29
30#ifdef GL_ES
31#define COMPAT_PRECISION mediump
32#else
33#define COMPAT_PRECISION
34#endif
35
36COMPAT_ATTRIBUTE vec4 VertexCoord;
37COMPAT_ATTRIBUTE vec4 COLOR;
38COMPAT_ATTRIBUTE vec4 TexCoord;
39COMPAT_VARYING vec4 COL0;
40COMPAT_VARYING vec4 TEX0;
41// out variables go here as COMPAT_VARYING whatever
42
43vec4 _oPosition1;
44uniform mat4 MVPMatrix;
45uniform COMPAT_PRECISION int FrameDirection;
46uniform COMPAT_PRECISION int FrameCount;
47uniform COMPAT_PRECISION vec2 OutputSize;
48uniform COMPAT_PRECISION vec2 TextureSize;
49uniform COMPAT_PRECISION vec2 InputSize;
50
51// compatibility #defines
52#define vTexCoord TEX0.xy
53#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
54#define OutSize vec4(OutputSize, 1.0 / OutputSize)
55
56void main()
57{
58    gl_Position = MVPMatrix * VertexCoord;
59    TEX0.xy = VertexCoord.xy;
60// Paste vertex contents here:
61}
62
63#elif defined(FRAGMENT)
64
65#if __VERSION__ >= 130
66#define COMPAT_VARYING in
67#define COMPAT_TEXTURE texture
68out vec4 FragColor;
69#else
70#define COMPAT_VARYING varying
71#define FragColor gl_FragColor
72#define COMPAT_TEXTURE texture2D
73#endif
74
75#ifdef GL_ES
76#ifdef GL_FRAGMENT_PRECISION_HIGH
77precision highp float;
78#else
79precision mediump float;
80#endif
81#define COMPAT_PRECISION mediump
82#else
83#define COMPAT_PRECISION
84#endif
85
86uniform COMPAT_PRECISION int FrameDirection;
87uniform COMPAT_PRECISION int FrameCount;
88uniform COMPAT_PRECISION vec2 OutputSize;
89uniform COMPAT_PRECISION vec2 TextureSize;
90uniform COMPAT_PRECISION vec2 InputSize;
91uniform sampler2D Texture;
92COMPAT_VARYING vec4 TEX0;
93// in variables go here as COMPAT_VARYING whatever
94
95// compatibility #defines
96#define Source Texture
97#define vTexCoord TEX0.xy
98
99#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize
100#define OutSize vec4(OutputSize, 1.0 / OutputSize)
101
102// delete all 'params.' or 'registers.' or whatever in the fragment
103float iGlobalTime = float(FrameCount)*0.025;
104vec2 iResolution = OutputSize.xy;
105
106
107// SHOWING RESOLUTION VS SAMPLES VS MOTION
108//
109// Warning full-screen on a slow machine is a likely TDR!!!!
110// I'm too afraid to try it, so this is tuned to the standard 1920x1080 shadertoy view in a browser.
111// Shader built and tested only on a laptop, probably fine on big desktop GPU.
112//
113// Each pair of rows has same number of shaded samples.
114// Samples are shaded either to white or black.
115// Top of pair is at full resolution.
116// Bottom of pair is at 1/2 resolution (aka 1/4 area).
117// Shows geometric aliasing in motion.
118//
119// Rows from top to bottom,
120//
121//  1x       at full resolution
122//  4xSGSSAA at 1/4 area in resolution
123//
124//  2xSGSSAA at full resolution
125//  8xSGSSAA at 1/4 area in resolution
126//
127//  4xSGSSAA at full resolution
128// 16xSGSSAA at 1/4 area in resolution
129//
130//  8xSGSSAA at full resolution
131// 32xSGSSAA at 1/4 area in resolution
132//
133// 16xSGSSAA at full resolution
134// 64xSGSSAA at 1/4 area in resolution
135//
136// Since everything is exactly up/down this SGSSAA simplifies to sampling in a line...
137// Resolve is a simple cubic filter which is larger than a pixel.
138//
139// Precision in motion = resolution * intensity steps as edge moves across pixel.
140//
141// For the same number of samples the lower resolution display
142// offers better motion precision but with compromized sharpness.
143// The extra spatial precision for the lower resolution display
144// is a product of being able to adjust sampling locations
145// from exactly resolving detail in the rectangular grid,
146// to better resolving sub-pixel position.
147// providing more effective intensity steps as a edge moves across a pixel.
148
149// Types.
150#define F1 float
151#define F2 vec2
152#define F3 vec3
153#define F4 vec4
154#define S1 int
155#define S2 int2
156#define S3 int3
157#define S4 int4
158
159// Controls.
160#define BARS (1.0/6000.0)
161#define THROW (16.0/1.0)
162#define SPEED (1.0/4.0)
163
164// Generates the source image.
165F1 Src(F1 x){return fract(x*x*BARS)<0.5?0.0:1.0;}
166
167// Convert from linear to sRGB.
168F1 Srgb(F1 c){return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);}
169
170// Filter as Cubic B-spline (x = distance from center).
171// General Mitchell-Netravali filter,
172//   http://www.cs.utexas.edu/users/fussell/courses/cs384g/lectures/mitchell/Mitchell.pdf
173F1 Filter(F1 x){
174  F1 b=1.0,c=0.0;
175  if(abs(x)<1.0)return(1.0/6.0)*((12.0-9.0*b-6.0*c)*x*x*abs(x)+(-18.0+12.0*b+6.0*c)*x*x+(6.0-2.0*b));
176  if(abs(x)<2.0)return(1.0/6.0)*((-b-6.0*c)*x*x*abs(x)+(6.0*b+30.0*c)*x*x+(-12.0*b-48.0*c)*abs(x)+(8.0*b+24.0*c));
177  return 0.0;}
178
179// Generates a swatch to test resolution and sample settings.
180F1 Swatch(F1 x,F1 o,F1 res,S1 num) {
181  // Filter sums.
182  F1 rSum=0.0;
183  F1 wSum=0.0;
184  F1 rSum2=0.0;
185  F1 wSum2=0.0;
186  // Base and stride for sampling.
187  F1 xBase=(floor(x/res)+(0.5/F1(num)))*res-(res*1.5);
188  F1 xStride=res/F1(num);
189  F1 xMid=(floor(x/res)+0.5)*res-(res*1.0);
190  // Filtering.
191  F1 xCenter=x+0.5;
192  F1 xScale=1.0/res;
193  F1 xScale2=1.0/res;
194  F1 p,r,w;
195  F1 r0,r1,r2;
196  F1 p0,p1,p2;
197  //
198  if(num==1){return Src((floor(x/res)+(0.5/F1(num)))*res+o);}
199  //
200  if(num==2){
201    p0=xMid;
202    for(S1 i=0;i<2*2;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
203    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
204    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
205    p1=xMid;
206    for(S1 i=0;i<2*2;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
207    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
208    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
209    p2=xMid;
210    for(S1 i=0;i<2*2;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
211    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
212    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
213    return rSum2/wSum2;}
214  //
215  if(num==4){
216    p0=xMid;
217    for(S1 i=0;i<2*4;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
218    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
219    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
220    p1=xMid;
221    for(S1 i=0;i<2*4;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
222    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
223    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
224    p2=xMid;
225    for(S1 i=0;i<2*4;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
226    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
227    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
228    return rSum2/wSum2;}
229  //
230  if(num==8){
231    p0=xMid;
232    for(S1 i=0;i<2*8;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
233    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
234    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
235    p1=xMid;
236    for(S1 i=0;i<2*8;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
237    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
238    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
239    p2=xMid;
240    for(S1 i=0;i<2*8;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
241    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
242    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
243    return rSum2/wSum2;}
244  //
245  if(num==16){
246    p0=xMid;
247    for(S1 i=0;i<2*16;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
248    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
249    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
250    p1=xMid;
251    for(S1 i=0;i<2*16;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
252    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
253    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
254    p2=xMid;
255    for(S1 i=0;i<2*16;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
256    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
257    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
258    return rSum2/wSum2;}
259  //
260  if(num==32){
261    p0=xMid;
262    for(S1 i=0;i<2*32;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
263    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
264    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
265    p1=xMid;
266    for(S1 i=0;i<2*32;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
267    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
268    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
269    p2=xMid;
270    for(S1 i=0;i<2*32;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
271    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
272    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
273    return rSum2/wSum2;}
274  //
275  if(num==64){
276    p0=xMid;
277    for(S1 i=0;i<2*64;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
278    r0=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
279    w=Filter(abs(p0-xCenter)*xScale2);rSum2+=r0*w;wSum2+=w;
280    p1=xMid;
281    for(S1 i=0;i<2*64;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
282    r1=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
283    w=Filter(abs(p1-xCenter)*xScale2);rSum2+=r1*w;wSum2+=w;
284    p2=xMid;
285    for(S1 i=0;i<2*64;i++){p=xBase+F1(i)*xStride;r=Src(p+o);w=Filter(abs(p-xMid)*xScale);rSum+=r*w;wSum+=w;}
286    r2=rSum/wSum;xBase+=res;xMid+=res;rSum=0.0;wSum=0.0;
287    w=Filter(abs(p2-xCenter)*xScale2);rSum2+=r2*w;wSum2+=w;
288    return rSum2/wSum2;}
289  //
290  return 0.0;}
291
292// Shader.
293void mainImage(out F4 fragColor,in F2 fragCoord){
294  F1 x=fragCoord.x;
295  F1 y=1.0-fragCoord.y/iResolution.y;
296  F1 o=sin(iGlobalTime*SPEED)*THROW;
297  fragColor.g=0.0;
298  if((y>0.04)&&(y<0.09))     fragColor.g=Swatch(x,o,1.0,1);
299  else if((y>0.11)&&(y<0.16))fragColor.g=Swatch(x,o,2.0,4);
300  //
301  else if((y>0.24)&&(y<0.29))fragColor.g=Swatch(x,o,1.0,2);
302  else if((y>0.31)&&(y<0.36))fragColor.g=Swatch(x,o,2.0,8);
303  //
304  else if((y>0.44)&&(y<0.49))fragColor.g=Swatch(x,o,1.0,4);
305  else if((y>0.51)&&(y<0.56))fragColor.g=Swatch(x,o,2.0,16);
306  //
307  else if((y>0.64)&&(y<0.69))fragColor.g=Swatch(x,o,1.0,8);
308  else if((y>0.71)&&(y<0.76))fragColor.g=Swatch(x,o,2.0,32);
309  //
310  else if((y>0.84)&&(y<0.89))fragColor.g=Swatch(x,o,1.0,16);
311  else if((y>0.91)&&(y<0.96))fragColor.g=Swatch(x,o,2.0,64);
312  //
313  fragColor.g = Srgb(fragColor.g);
314  fragColor.rgb = fragColor.ggg;
315  fragColor.a = 0.0;
316}
317
318 void main(void)
319{
320  //just some shit to wrap shadertoy's stuff
321  vec2 FragCoord = vTexCoord.xy*OutputSize.xy;
322  mainImage(FragColor,FragCoord);
323}
324#endif
325