fxaa.fragment.fx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. uniform sampler2D textureSampler;
  2. uniform vec2 texelSize;
  3. varying vec2 vUV;
  4. varying vec2 sampleCoordS;
  5. varying vec2 sampleCoordE;
  6. varying vec2 sampleCoordN;
  7. varying vec2 sampleCoordW;
  8. varying vec2 sampleCoordNW;
  9. varying vec2 sampleCoordSE;
  10. varying vec2 sampleCoordNE;
  11. varying vec2 sampleCoordSW;
  12. const float fxaaQualitySubpix = 1.0;
  13. const float fxaaQualityEdgeThreshold = 0.166;
  14. const float fxaaQualityEdgeThresholdMin = 0.0833;
  15. const vec3 kLumaCoefficients = vec3(0.2126, 0.7152, 0.0722);
  16. #define FxaaLuma(rgba) dot(rgba.rgb, kLumaCoefficients)
  17. void main(){
  18. vec2 posM;
  19. posM.x = vUV.x;
  20. posM.y = vUV.y;
  21. vec4 rgbyM = texture2D(textureSampler, vUV, 0.0);
  22. float lumaM = FxaaLuma(rgbyM);
  23. float lumaS = FxaaLuma(texture2D(textureSampler, sampleCoordS, 0.0));
  24. float lumaE = FxaaLuma(texture2D(textureSampler, sampleCoordE, 0.0));
  25. float lumaN = FxaaLuma(texture2D(textureSampler, sampleCoordN, 0.0));
  26. float lumaW = FxaaLuma(texture2D(textureSampler, sampleCoordW, 0.0));
  27. float maxSM = max(lumaS, lumaM);
  28. float minSM = min(lumaS, lumaM);
  29. float maxESM = max(lumaE, maxSM);
  30. float minESM = min(lumaE, minSM);
  31. float maxWN = max(lumaN, lumaW);
  32. float minWN = min(lumaN, lumaW);
  33. float rangeMax = max(maxWN, maxESM);
  34. float rangeMin = min(minWN, minESM);
  35. float rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
  36. float range = rangeMax - rangeMin;
  37. float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
  38. #ifndef MALI
  39. if(range < rangeMaxClamped)
  40. {
  41. gl_FragColor = rgbyM;
  42. return;
  43. }
  44. #endif
  45. float lumaNW = FxaaLuma(texture2D(textureSampler, sampleCoordNW, 0.0));
  46. float lumaSE = FxaaLuma(texture2D(textureSampler, sampleCoordSE, 0.0));
  47. float lumaNE = FxaaLuma(texture2D(textureSampler, sampleCoordNE, 0.0));
  48. float lumaSW = FxaaLuma(texture2D(textureSampler, sampleCoordSW, 0.0));
  49. float lumaNS = lumaN + lumaS;
  50. float lumaWE = lumaW + lumaE;
  51. float subpixRcpRange = 1.0 / range;
  52. float subpixNSWE = lumaNS + lumaWE;
  53. float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
  54. float edgeVert1 = (-2.0 * lumaM) + lumaWE;
  55. float lumaNESE = lumaNE + lumaSE;
  56. float lumaNWNE = lumaNW + lumaNE;
  57. float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
  58. float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
  59. float lumaNWSW = lumaNW + lumaSW;
  60. float lumaSWSE = lumaSW + lumaSE;
  61. float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
  62. float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
  63. float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
  64. float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
  65. float edgeHorz = abs(edgeHorz3) + edgeHorz4;
  66. float edgeVert = abs(edgeVert3) + edgeVert4;
  67. float subpixNWSWNESE = lumaNWSW + lumaNESE;
  68. float lengthSign = texelSize.x;
  69. bool horzSpan = edgeHorz >= edgeVert;
  70. float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
  71. if (!horzSpan)
  72. {
  73. lumaN = lumaW;
  74. }
  75. if (!horzSpan)
  76. {
  77. lumaS = lumaE;
  78. }
  79. if (horzSpan)
  80. {
  81. lengthSign = texelSize.y;
  82. }
  83. float subpixB = (subpixA * (1.0 / 12.0)) - lumaM;
  84. float gradientN = lumaN - lumaM;
  85. float gradientS = lumaS - lumaM;
  86. float lumaNN = lumaN + lumaM;
  87. float lumaSS = lumaS + lumaM;
  88. bool pairN = abs(gradientN) >= abs(gradientS);
  89. float gradient = max(abs(gradientN), abs(gradientS));
  90. if (pairN)
  91. {
  92. lengthSign = -lengthSign;
  93. }
  94. float subpixC = clamp(abs(subpixB) * subpixRcpRange, 0.0, 1.0);
  95. vec2 posB;
  96. posB.x = posM.x;
  97. posB.y = posM.y;
  98. vec2 offNP;
  99. offNP.x = (!horzSpan) ? 0.0 : texelSize.x;
  100. offNP.y = (horzSpan) ? 0.0 : texelSize.y;
  101. if (!horzSpan)
  102. {
  103. posB.x += lengthSign * 0.5;
  104. }
  105. if (horzSpan)
  106. {
  107. posB.y += lengthSign * 0.5;
  108. }
  109. vec2 posN;
  110. posN.x = posB.x - offNP.x * 1.5;
  111. posN.y = posB.y - offNP.y * 1.5;
  112. vec2 posP;
  113. posP.x = posB.x + offNP.x * 1.5;
  114. posP.y = posB.y + offNP.y * 1.5;
  115. float subpixD = ((-2.0) * subpixC) + 3.0;
  116. float lumaEndN = FxaaLuma(texture2D(textureSampler, posN, 0.0));
  117. float subpixE = subpixC * subpixC;
  118. float lumaEndP = FxaaLuma(texture2D(textureSampler, posP, 0.0));
  119. if (!pairN)
  120. {
  121. lumaNN = lumaSS;
  122. }
  123. float gradientScaled = gradient * 1.0 / 4.0;
  124. float lumaMM = lumaM - lumaNN * 0.5;
  125. float subpixF = subpixD * subpixE;
  126. bool lumaMLTZero = lumaMM < 0.0;
  127. lumaEndN -= lumaNN * 0.5;
  128. lumaEndP -= lumaNN * 0.5;
  129. bool doneN = abs(lumaEndN) >= gradientScaled;
  130. bool doneP = abs(lumaEndP) >= gradientScaled;
  131. if (!doneN)
  132. {
  133. posN.x -= offNP.x * 3.0;
  134. }
  135. if (!doneN)
  136. {
  137. posN.y -= offNP.y * 3.0;
  138. }
  139. bool doneNP = (!doneN) || (!doneP);
  140. if (!doneP)
  141. {
  142. posP.x += offNP.x * 3.0;
  143. }
  144. if (!doneP)
  145. {
  146. posP.y += offNP.y * 3.0;
  147. }
  148. if (doneNP)
  149. {
  150. if (!doneN) lumaEndN = FxaaLuma(texture2D(textureSampler, posN.xy, 0.0));
  151. if (!doneP) lumaEndP = FxaaLuma(texture2D(textureSampler, posP.xy, 0.0));
  152. if (!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  153. if (!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  154. doneN = abs(lumaEndN) >= gradientScaled;
  155. doneP = abs(lumaEndP) >= gradientScaled;
  156. if (!doneN) posN.x -= offNP.x * 12.0;
  157. if (!doneN) posN.y -= offNP.y * 12.0;
  158. doneNP = (!doneN) || (!doneP);
  159. if (!doneP) posP.x += offNP.x * 12.0;
  160. if (!doneP) posP.y += offNP.y * 12.0;
  161. }
  162. float dstN = posM.x - posN.x;
  163. float dstP = posP.x - posM.x;
  164. if (!horzSpan)
  165. {
  166. dstN = posM.y - posN.y;
  167. }
  168. if (!horzSpan)
  169. {
  170. dstP = posP.y - posM.y;
  171. }
  172. bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
  173. float spanLength = (dstP + dstN);
  174. bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
  175. float spanLengthRcp = 1.0 / spanLength;
  176. bool directionN = dstN < dstP;
  177. float dst = min(dstN, dstP);
  178. bool goodSpan = directionN ? goodSpanN : goodSpanP;
  179. float subpixG = subpixF * subpixF;
  180. float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
  181. float subpixH = subpixG * fxaaQualitySubpix;
  182. float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
  183. float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
  184. if (!horzSpan)
  185. {
  186. posM.x += pixelOffsetSubpix * lengthSign;
  187. }
  188. if (horzSpan)
  189. {
  190. posM.y += pixelOffsetSubpix * lengthSign;
  191. }
  192. #ifdef MALI
  193. if(range < rangeMaxClamped)
  194. {
  195. gl_FragColor = rgbyM;
  196. }
  197. else
  198. {
  199. gl_FragColor = texture2D(textureSampler, posM, 0.0);
  200. }
  201. #else
  202. gl_FragColor = texture2D(textureSampler, posM, 0.0);
  203. #endif
  204. }