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