smaa.effect 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
  2. CCEffect %{
  3. temporaries:
  4. s1: &s1 {
  5. minFilter: linear,
  6. magFilter: linear,
  7. addressU: clamp,
  8. addressV: clamp,
  9. }
  10. s2: &s2 {
  11. minFilter: point,
  12. magFilter: point,
  13. addressU: clamp,
  14. addressV: clamp,
  15. }
  16. techniques:
  17. - name: smaa
  18. passes:
  19. - vert: smaa-edge-vs:vert
  20. frag: smaa-edge-fs:frag
  21. depthStencilState:
  22. depthTest: false
  23. depthWrite: false
  24. properties:
  25. u_texSampler: { sampler: *s1 }
  26. - vert: smaa-blend-vs:vert
  27. frag: smaa-blend-fs:frag
  28. depthStencilState:
  29. depthTest: false
  30. depthWrite: false
  31. properties:
  32. u_edgeTexSampler: { sampler: *s1 }
  33. u_areaTexSampler: { sampler: *s1 }
  34. u_searchTexSampler: { sampler: *s2 }
  35. }%
  36. CCProgram smaa-edge-vs %{
  37. precision highp float;
  38. #include <builtin/uniforms/cc-global>
  39. in vec2 a_position;
  40. in vec2 a_texCoord;
  41. out vec2 v_uv;
  42. out vec4 v_offsets[3];
  43. vec4 vert () {
  44. vec4 pos = vec4(a_position, 0.0, 1.0);
  45. v_uv = a_texCoord * cc_screenScale.xy;
  46. v_offsets[0] = v_uv.xyxy + cc_nativeSize.zwzw * vec4(-1.0, 0.0, 0.0, 1.0);
  47. v_offsets[1] = v_uv.xyxy + cc_nativeSize.zwzw * vec4( 1.0, 0.0, 0.0, -1.0);
  48. v_offsets[2] = v_uv.xyxy + cc_nativeSize.zwzw * vec4(-2.0, 0.0, 0.0, 2.0);
  49. return pos;
  50. }
  51. }%
  52. CCProgram smaa-edge-fs %{
  53. precision highp float;
  54. #include <builtin/uniforms/cc-global>
  55. #include <common/common-define>
  56. #include <common/color/gamma>
  57. #include <common/color/aces>
  58. #pragma define SMAA_THRESHOLD 0.1
  59. in vec2 v_uv;
  60. in vec4 v_offsets[3];
  61. uniform sampler2D u_texSampler;
  62. vec3 ToLDR(vec3 color) {
  63. #if CC_USE_HDR
  64. color *= cc_exposure.x * FP_SCALE_INV;
  65. color = ACESToneMap(color);
  66. color = LinearToSRGB(color);
  67. #endif
  68. return color;
  69. }
  70. vec4 frag () {
  71. vec2 threshold = vec2(SMAA_THRESHOLD, SMAA_THRESHOLD);
  72. vec4 delta;
  73. vec3 C = ToLDR(texture(u_texSampler, v_uv).rgb);
  74. vec3 Cleft = ToLDR(texture(u_texSampler, v_offsets[0].xy).rgb);
  75. vec3 t = abs(C - Cleft);
  76. delta.x = max(max(t.r, t.g), t.b);
  77. vec3 Ctop = ToLDR(texture(u_texSampler, v_offsets[0].zw).rgb);
  78. t = abs(C - Ctop);
  79. delta.y = max(max(t.r, t.g), t.b);
  80. vec2 edges = step(threshold, delta.xy);
  81. if (dot(edges, vec2(1.0, 1.0)) == 0.0)
  82. discard;
  83. vec3 Cright = ToLDR(texture(u_texSampler, v_offsets[1].xy).rgb);
  84. t = abs(C - Cright);
  85. delta.z = max(max(t.r, t.g), t.b);
  86. vec3 Cbottom = ToLDR(texture(u_texSampler, v_offsets[1].zw).rgb);
  87. t = abs(C - Cbottom);
  88. delta.w = max(max(t.r, t.g), t.b);
  89. float maxDelta = max(max(max(delta.x, delta.y), delta.z), delta.w);
  90. vec3 Cleftleft = ToLDR(texture(u_texSampler, v_offsets[2].xy).rgb);
  91. t = abs(C - Cleftleft);
  92. delta.z = max(max(t.r, t.g), t.b);
  93. vec3 Ctoptop = ToLDR(texture(u_texSampler, v_offsets[2].zw).rgb);
  94. t = abs(C - Ctoptop);
  95. delta.w = max(max(t.r, t.g), t.b);
  96. maxDelta = max(max(maxDelta, delta.z), delta.w);
  97. edges.xy *= step(0.5 * maxDelta, delta.xy);
  98. vec4 o = vec4(edges, 0.0, 0.0);
  99. return o;
  100. }
  101. }%
  102. CCProgram smaa-blend-vs %{
  103. precision highp float;
  104. #include <builtin/uniforms/cc-global>
  105. #pragma define SMAA_MAX_SEARCH_STEPS 8
  106. in vec2 a_position;
  107. in vec2 a_texCoord;
  108. out vec2 v_uv;
  109. out vec4 v_offsets[3];
  110. out vec2 v_pixCoord;
  111. vec4 vert () {
  112. vec4 pos = vec4(a_position, 0.0, 1.0);
  113. v_uv = a_texCoord * cc_screenScale.xy;
  114. v_pixCoord = v_uv * cc_nativeSize.xy;
  115. v_offsets[0] = v_uv.xyxy + cc_nativeSize.zwzw * vec4(-0.25, 0.125, 1.25, 0.125);
  116. v_offsets[1] = v_uv.xyxy + cc_nativeSize.zwzw * vec4(-0.125, 0.25, -0.125, -1.25);
  117. v_offsets[2] = vec4(v_offsets[0].xz, v_offsets[1].yw) + vec4(-2.0, 2.0, -2.0, 2.0) * cc_nativeSize.zzww * float(SMAA_MAX_SEARCH_STEPS);
  118. return pos;
  119. }
  120. }%
  121. CCProgram smaa-blend-fs %{
  122. precision highp float;
  123. #include <builtin/uniforms/cc-global>
  124. #pragma define SMAA_MAX_SEARCH_STEPS 8
  125. #pragma define SMAA_AREATEX_MAX_DISTANCE 16
  126. #pragma define SMAA_AREATEX_PIXEL_SIZE (1.0 / vec2(160.0, 560.0))
  127. #pragma define SMAA_AREATEX_SUBTEX_SIZE (1.0 / 7.0)
  128. in vec2 v_uv;
  129. in vec4 v_offsets[3];
  130. in vec2 v_pixCoord;
  131. uniform sampler2D u_edgeTexSampler;
  132. uniform sampler2D u_areaTexSampler;
  133. uniform sampler2D u_searchTexSampler;
  134. float SMAASearchLength(vec2 e, float bias, float scale) {
  135. e.r = bias + e.r * scale;
  136. return 255.0 * texture(u_searchTexSampler, e).r;
  137. }
  138. float SMAASearchXLeft(vec2 texcoord, float end) {
  139. vec2 e = vec2(0.0, 1.0);
  140. for (int i = 0; i < SMAA_MAX_SEARCH_STEPS; ++i) {
  141. e = texture(u_edgeTexSampler, texcoord).rg;
  142. texcoord -= vec2( 2.0, 0.0 ) * cc_nativeSize.zw;
  143. if (!(texcoord.x > end && e.g > 0.8281 && e.r == 0.0))
  144. break;
  145. }
  146. texcoord.x += 0.25 * cc_nativeSize.z;
  147. texcoord.x += cc_nativeSize.z;
  148. texcoord.x += 2.0 * cc_nativeSize.z;
  149. texcoord.x -= cc_nativeSize.z * SMAASearchLength(e, 0.0, 0.5);
  150. return texcoord.x;
  151. }
  152. float SMAASearchXRight(vec2 texcoord, float end) {
  153. vec2 e = vec2(0.0, 1.0);
  154. for (int i = 0; i < SMAA_MAX_SEARCH_STEPS; ++i) {
  155. e = texture(u_edgeTexSampler, texcoord).rg;
  156. texcoord += vec2( 2.0, 0.0 ) * cc_nativeSize.zw;
  157. if (!(texcoord.x < end && e.g > 0.8281 && e.r == 0.0))
  158. break;
  159. }
  160. texcoord.x -= 0.25 * cc_nativeSize.z;
  161. texcoord.x -= cc_nativeSize.z;
  162. texcoord.x -= 2.0 * cc_nativeSize.z;
  163. texcoord.x += cc_nativeSize.z * SMAASearchLength(e, 0.5, 0.5);
  164. return texcoord.x;
  165. }
  166. float SMAASearchYUp(vec2 texcoord, float end) {
  167. vec2 e = vec2(1.0, 0.0);
  168. for (int i = 0; i < SMAA_MAX_SEARCH_STEPS; ++i) {
  169. e = texture(u_edgeTexSampler, texcoord).rg;
  170. texcoord += vec2( 0.0, 2.0 ) * cc_nativeSize.zw;
  171. if (!(texcoord.y > end && e.r > 0.8281 && e.g == 0.0))
  172. break;
  173. }
  174. texcoord.y -= 0.25 * cc_nativeSize.w;
  175. texcoord.y -= cc_nativeSize.w;
  176. texcoord.y -= 2.0 * cc_nativeSize.w;
  177. texcoord.y += cc_nativeSize.w * SMAASearchLength(e.gr, 0.0, 0.5);
  178. return texcoord.y;
  179. }
  180. float SMAASearchYDown(vec2 texcoord, float end) {
  181. vec2 e = vec2(1.0, 0.0);
  182. for (int i = 0; i < SMAA_MAX_SEARCH_STEPS; ++i) {
  183. e = texture(u_edgeTexSampler, texcoord).rg;
  184. texcoord -= vec2( 0.0, 2.0 ) * cc_nativeSize.zw;
  185. if (!(texcoord.y < end && e.r > 0.8281 && e.g == 0.0))
  186. break;
  187. }
  188. texcoord.y += 0.25 * cc_nativeSize.w;
  189. texcoord.y += cc_nativeSize.w;
  190. texcoord.y += 2.0 * cc_nativeSize.w;
  191. texcoord.y -= cc_nativeSize.w * SMAASearchLength(e.gr, 0.5, 0.5);
  192. return texcoord.y;
  193. }
  194. vec2 Round(vec2 x) {
  195. return sign(x) * floor(abs(x) + 0.5);
  196. }
  197. vec2 SMAAArea(vec2 dist, float e1, float e2) {
  198. vec2 texcoord = float(SMAA_AREATEX_MAX_DISTANCE) * Round(4.0 * vec2(e1, e2)) + dist;
  199. texcoord = SMAA_AREATEX_PIXEL_SIZE * texcoord + 0.5 * SMAA_AREATEX_PIXEL_SIZE;
  200. return texture(u_areaTexSampler, texcoord).rg;
  201. }
  202. vec4 frag () {
  203. vec4 weights = vec4(0.0);
  204. vec2 e = texture(u_edgeTexSampler, v_uv).rg;
  205. vec2 d;
  206. vec2 coords;
  207. if ( e.g > 0.0 ) {
  208. coords.x = SMAASearchXLeft(v_offsets[0].xy, v_offsets[2].x);
  209. coords.y = v_offsets[1].y;
  210. d.x = coords.x;
  211. float e1 = texture(u_edgeTexSampler, coords).r;
  212. coords.x = SMAASearchXRight(v_offsets[0].zw, v_offsets[2].y);
  213. d.y = coords.x;
  214. d = d / cc_nativeSize.z - v_pixCoord.x;
  215. vec2 sqrt_d = sqrt(abs(d));
  216. coords.y -= 1.0 * cc_nativeSize.w;
  217. float e2 = texture(u_edgeTexSampler, coords + vec2(cc_nativeSize.z, 0.0)).r;
  218. weights.rg = SMAAArea(sqrt_d, e1, e2);
  219. }
  220. if ( e.r > 0.0 ) {
  221. coords.y = SMAASearchYUp(v_offsets[1].xy, v_offsets[2].z);
  222. coords.x = v_offsets[0].x;
  223. d.x = coords.y;
  224. float e1 = texture(u_edgeTexSampler, coords).g;
  225. coords.y = SMAASearchYDown(v_offsets[1].zw, v_offsets[2].w);
  226. d.y = coords.y;
  227. d = d / cc_nativeSize.w - v_pixCoord.y;
  228. vec2 sqrt_d = sqrt(abs(d));
  229. coords.y -= 1.0 * cc_nativeSize.w;
  230. float e2 = texture(u_edgeTexSampler, coords + vec2(0.0, cc_nativeSize.w)).g;
  231. weights.ba = SMAAArea(sqrt_d, e1, e2);
  232. }
  233. return weights;
  234. }
  235. }%