mdapt-pass4.fs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // This is a port of the original CG shader to the quark format
  2. // the original shader can be found here :
  3. // https://github.com/libretro/common-shaders/tree/master/dithering/mdapt-4p
  4. /*
  5. Merge Dithering and Pseudo Transparency Shader v1.5 - Pass 4
  6. by Sp00kyFox, 2013
  7. Blends tagged pixels with tagged neighbors.
  8. */
  9. #version 150
  10. uniform sampler2D source[];
  11. uniform vec4 sourceSize[];
  12. uniform vec4 targetSize;
  13. in Vertex{
  14. vec2 texCoord;
  15. };
  16. out vec4 fragColor;
  17. bool eq(vec4 A, vec4 B)
  18. {
  19. return (A.x == B.x && A.y == B.y && A.z == B.z);
  20. }
  21. float remapFrom01(float v, float low, float high)
  22. {
  23. return round(mix(low, high, v));
  24. }
  25. vec3 merge3(vec4 C, vec4 A, vec4 B, float tag)
  26. {
  27. if(A.w == tag)
  28. {
  29. if(B.w == tag)
  30. return 0.5*C.xyz + 0.25*(A.xyz + B.xyz);
  31. else
  32. return 0.5*(C.xyz + A.xyz);
  33. }
  34. else if(B.w == tag)
  35. return 0.5*(C.xyz + B.xyz);
  36. else
  37. return C.xyz;
  38. }
  39. vec3 merge9(vec4 C, vec4 UL, vec4 UR, vec4 DL, vec4 DR, vec4 U1, vec4 D1, vec4 L1, vec4 R1)
  40. {
  41. //return 0.25*C.xyz + 0.0625*(UL.xyz + UR.xyz + DR.xyz + DL.xyz) + 0.125*(L1.xyz + R1.xyz + D1.xyz + U1.xyz);
  42. vec3 B = vec3(0.0);
  43. vec3 W = vec3(0.0);
  44. float cntB = 0;
  45. float cntW = 0;
  46. if(UL.w > 0 || eq(UL,C) || (D1.w > 0 && eq(UL,D1)) || (R1.w > 0 && eq(UL,R1)) )
  47. {
  48. B = B+UL.xyz;
  49. cntB++;
  50. }
  51. if(UR.w > 0 || eq(UR,C) || (D1.w > 0 && eq(UR,D1)) || (L1.w > 0 && eq(UR,L1)) )
  52. {
  53. B = B+UR.xyz;
  54. cntB++;
  55. }
  56. if(DL.w > 0 || eq(DL,C) || (U1.w > 0 && eq(DL,U1)) || (R1.w > 0 && eq(DL,R1)) )
  57. {
  58. B = B+DL.xyz;
  59. cntB++;
  60. }
  61. if(DR.w > 0 || eq(DR,C) || (U1.w > 0 && eq(DR,U1)) || (L1.w > 0 && eq(DR,L1)) )
  62. {
  63. B = B+DR.xyz;
  64. cntB++;
  65. }
  66. if(U1.w > 0 || eq(U1,C) || (D1.w > 0 && eq(U1,D1)) )
  67. {
  68. W = W+U1.xyz;
  69. cntW++;
  70. }
  71. if(D1.w > 0 || eq(D1,C) || (U1.w > 0 && eq(D1,U1)) )
  72. {
  73. W = W+D1.xyz;
  74. cntW++;
  75. }
  76. if(L1.w > 0 || eq(L1,C) || (R1.w > 0 && eq(L1,R1)) )
  77. {
  78. W = W+L1.xyz;
  79. cntW++;
  80. }
  81. if(R1.w > 0 || eq(R1,C) || (L1.w > 0 && eq(R1,L1)) )
  82. {
  83. W = W+R1.xyz;
  84. cntW++;
  85. }
  86. if(cntB == 0)
  87. {
  88. if(cntW == 0)
  89. return C.xyz;
  90. else
  91. return 0.5*C.xyz + (1/(cntW*2))*W;
  92. }
  93. if(cntW == 0)
  94. return 0.5*C.xyz + (1/(cntB*2))*B;
  95. else
  96. return 0.25*C.xyz + (1/(cntB*4))*B + (1/(cntW*2))*W;
  97. }
  98. void main(void) {
  99. vec2 pos = texCoord*sourceSize[0].xy; // pos = pixel position
  100. vec2 dir = sign(pos); // dir = pixel direction
  101. vec2 g1 = dir*vec2(sourceSize[0].z,0.0);
  102. vec2 g2 = dir*vec2(0.0,sourceSize[0].w);
  103. /*
  104. UL U1 UR
  105. L1 C R1
  106. DL D1 DR
  107. */
  108. vec4 C = texture(source[0], texCoord).xyzw;
  109. vec4 L1 = texture(source[0], texCoord - g1).xyzw;
  110. vec4 R1 = texture(source[0], texCoord + g1).xyzw;
  111. vec4 U1 = texture(source[0], texCoord - g2).xyzw;
  112. vec4 D1 = texture(source[0], texCoord + g2).xyzw;
  113. vec4 UL = texture(source[0], texCoord - g1 - g2).xyzw;
  114. vec4 UR = texture(source[0], texCoord + g1 - g2).xyzw;
  115. vec4 DL = texture(source[0], texCoord - g1 + g2).xyzw;
  116. vec4 DR = texture(source[0], texCoord + g1 + g2).xyzw;
  117. C.w = remapFrom01(C.w, 0, 15) - 2;
  118. L1.w = remapFrom01(L1.w, 0, 15) - 2;
  119. R1.w = remapFrom01(R1.w, 0, 15) - 2;
  120. U1.w = remapFrom01(U1.w, 0, 15) - 2;
  121. D1.w = remapFrom01(D1.w, 0, 15) - 2;
  122. UL.w = remapFrom01(UL.w, 0, 15) - 2;
  123. UR.w = remapFrom01(UR.w, 0, 15) - 2;
  124. DL.w = remapFrom01(DL.w, 0, 15) - 2;
  125. DR.w = remapFrom01(DR.w, 0, 15) - 2;
  126. /*
  127. tag values:
  128. 0 nothing
  129. checkerboard pattern
  130. 9 DL
  131. 8 DR
  132. 7 UR
  133. 6 UL
  134. 5 full
  135. horizontal two-line checkerboard
  136. 4 bottom line
  137. 3 upper line
  138. vertical two-line checkerboard
  139. 2 left line
  140. 1 right line
  141. one line dither
  142. -1 horizontal
  143. -2 vertical
  144. */
  145. // checkerboard pattern
  146. if(C.w > 0){
  147. fragColor=vec4(merge9(C,UL,UR,DL,DR,U1,D1,L1,R1),0);
  148. return;
  149. }
  150. // horizontal one line dither
  151. if(C.w == -1){
  152. fragColor=vec4(merge3(C,L1,R1,-1),0);
  153. return;
  154. }
  155. // vertical one line dither
  156. if(C.w == -2){
  157. fragColor=vec4(merge3(C,U1,D1,-2),0);
  158. return;
  159. }
  160. fragColor=vec4(C.xyz, 1.0);
  161. }