// This is a port of the original CG shader to the quark format // the original shader can be found here : // https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p /* Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 1 by Sp00kyFox, 2013 Finds specific patterns and tags their central pixel. */ #version 150 //#define HORI //#define VERT #define dtt vec3(65536,255,1) #define eq_threshold 5.0 uniform sampler2D source[]; uniform vec4 sourceSize[]; uniform vec4 targetSize; in Vertex{ vec2 texCoord; }; out vec4 fragColor; float reduce(vec3 color) { return dot(color, dtt); } float df(float A, float B) { return abs(A-B); } bool eq(float A, float B) { return (A == B); } float remapTo01(float v, float low, float high) { return clamp((v - low)/(high-low),0.0,1.0); } void main(void) { vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position vec2 dir = sign(pos); // dir = pixel direction vec2 g1 = dir*vec2(sourceSize[0].z,0.0); vec2 g2 = dir*vec2(0.0,sourceSize[0].w);; /* U3 UUL U2 UUR ULL UL U1 UR URR L3 L2 L1 C R1 R2 R3 DLL DL D1 DR DRR DDL D2 DDR D3 */ vec3 c = texture(source[0], texCoord).xyz; vec3 l1 = texture(source[0], texCoord - g1).xyz; vec3 l2 = texture(source[0], texCoord - 2*g1).xyz; vec3 r1 = texture(source[0], texCoord + g1).xyz; vec3 r2 = texture(source[0], texCoord + 2*g1).xyz; vec3 u1 = texture(source[0], texCoord - g2).xyz; vec3 u2 = texture(source[0], texCoord - 2*g2).xyz; vec3 d1 = texture(source[0], texCoord + g2).xyz; vec3 d2 = texture(source[0], texCoord + 2*g2).xyz; vec3 ul = texture(source[0], texCoord - g1 - g2).xyz; vec3 ur = texture(source[0], texCoord + g1 - g2).xyz; vec3 dl = texture(source[0], texCoord - g1 + g2).xyz; vec3 dr = texture(source[0], texCoord + g1 + g2).xyz; vec3 ull = texture(source[0], texCoord - 2*g1 - g2).xyz; vec3 uul = texture(source[0], texCoord - g1 - 2*g2).xyz; vec3 uur = texture(source[0], texCoord + g1 - 2*g2).xyz; vec3 urr = texture(source[0], texCoord + 2*g1 - g2).xyz; vec3 drr = texture(source[0], texCoord + 2*g1 + g2).xyz; vec3 ddr = texture(source[0], texCoord + g1 + 2*g2).xyz; vec3 ddl = texture(source[0], texCoord - g1 + 2*g2).xyz; vec3 dll = texture(source[0], texCoord - 2*g1 + g2).xyz; vec3 l3 = texture(source[0], texCoord - 3*g1).xyz; vec3 r3 = texture(source[0], texCoord + 3*g1).xyz; vec3 u3 = texture(source[0], texCoord - 3*g2).xyz; vec3 d3 = texture(source[0], texCoord + 3*g2).xyz; float C = reduce( c ); float L1 = reduce( l1 ); float U1 = reduce( u1 ); float L2 = reduce( l2 ); float U2 = reduce( u2 ); float R1 = reduce( r1 ); float D1 = reduce( d1 ); float R2 = reduce( r2 ); float D2 = reduce( d2 ); float UL = reduce( ul ); float L3 = reduce( l3 ); float UR = reduce( ur ); float R3 = reduce( r3 ); float DL = reduce( dl ); float U3 = reduce( u3 ); float DR = reduce( dr ); float D3 = reduce( d3 ); float ULL = reduce( ull ); float DRR = reduce( drr ); float UUL = reduce( uul ); float DDR = reduce( ddr ); float UUR = reduce( uur ); float DDL = reduce( ddl ); float URR = reduce( urr ); float DLL = reduce( dll ); /* tag values: 0 nothing checkerboard pattern 9 DL 8 DR 7 UR 6 UL 5 full horizontal two-line checkerboard 4 bottom line 3 upper line vertical two-line checkerboard 2 left line 1 right line one line dither -1 horizontal -2 vertical */ float type=0; // checkerboard pattern if(!eq(C,D1) && !eq(C,U1) && !eq(C,L1) && !eq(C,R1)) { if(eq(C,UL)) { if(eq(C,UR)) { if(eq(C,DR)) { if(eq(C,DL)) type = 5; else if(!eq(D1,L1) || eq(D1,DL)) type = 9; } else { if(eq(C,DL) && (!eq(D1,R1) || eq(D1,DR))) type = 8; } } else { if(eq(C,DR) && eq(C,DL) && (!eq(U1,R1) || eq(U1,UR))) type = 7; } } else if(eq(C,UR) && eq(C,DR) && eq(C,DL) && (!eq(U1,L1) || eq(U1,UL))) type = 6; } // horizontal two-line checkerboard else if(eq(C,L2) && eq(C,R2) && eq(C,UL) && eq(C,UR) && !eq(C,L1) && !eq(C,R1) && !eq(C,ULL) && !eq(C,U1) && !eq(C,URR)) { type = 4; } else if(eq(C,L2) && eq(C,R2) && eq(C,DL) && eq(C,DR) && !eq(C,L1) && !eq(C,R1) && !eq(C,DLL) && !eq(C,D1) && !eq(C,DRR)) { type = 3; } // vertical two-line checkerboard else if(eq(C,U2) && eq(C,D2) && eq(C,UR) && eq(C,DR) && !eq(C,U1) && !eq(C,D1) && !eq(C,R1) && !eq(C,UUR) && !eq(C,DDR)) { type = 2; } else if(eq(C,U2) && eq(C,D2) && eq(C,UL) && eq(C,DL) && !eq(C,U1) && !eq(C,D1) && !eq(C,L1) && !eq(C,UUL) && !eq(C,DDL)) { type = 1; } #ifdef HORI // horizontal one line dither else if(eq(C,L2) && eq(C,R2) && eq(L1,R1) && !eq(C,L1) && !eq(C,L3) && !eq(C,R3)) type = -1; #endif #ifdef VERT // vertical one line dither else if(eq(C,U2) && eq(C,D2) && eq(U1,D1) && !eq(C,U1) && !eq(C,U3) && !eq(C,D3)) type = -2; #endif fragColor=vec4(c, remapTo01(type+2, 0, 15)); }