FXAA3.hlsl 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. //----------------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions
  7. // are met:
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright
  11. // notice, this list of conditions and the following disclaimer in the
  12. // documentation and/or other materials provided with the distribution.
  13. // * Neither the name of NVIDIA CORPORATION nor the names of its
  14. // contributors may be used to endorse or promote products derived
  15. // from this software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
  18. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  21. // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  22. // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  23. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  24. // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  25. // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. //
  29. //----------------------------------------------------------------------------------
  30. /*============================================================================
  31. NVIDIA FXAA 3.11 by TIMOTHY LOTTES
  32. ------------------------------------------------------------------------------
  33. Modified for Urho3D
  34. ============================================================================*/
  35. /*==========================================================================*/
  36. //
  37. // Urho3D specific preparations
  38. //
  39. /*--------------------------------------------------------------------------*/
  40. #include "Uniforms.hlsl"
  41. #include "Samplers.hlsl"
  42. #include "Transform.hlsl"
  43. #include "ScreenPos.hlsl"
  44. /*============================================================================
  45. FXAA QUALITY - TUNING KNOBS
  46. ------------------------------------------------------------------------------
  47. NOTE the other tuning knobs are now in the shader function inputs!
  48. ============================================================================*/
  49. #ifndef FXAA_QUALITY_PRESET
  50. //
  51. // Choose the quality preset.
  52. // This needs to be compiled into the shader as it effects code.
  53. // Best option to include multiple presets is to
  54. // in each shader define the preset, then include this file.
  55. //
  56. // OPTIONS
  57. // -----------------------------------------------------------------------
  58. // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
  59. // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
  60. // 39 - no dither, very expensive
  61. //
  62. // NOTES
  63. // -----------------------------------------------------------------------
  64. // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
  65. // 13 = about same speed as FXAA 3.9 and better than 12
  66. // 23 = closest to FXAA 3.9 visually and performance wise
  67. // _ = the lowest digit is directly related to performance
  68. // _ = the highest digit is directly related to style
  69. //
  70. #define FXAA_QUALITY_PRESET 12
  71. #endif
  72. /*============================================================================
  73. FXAA QUALITY - PRESETS
  74. ============================================================================*/
  75. /*============================================================================
  76. FXAA QUALITY - MEDIUM DITHER PRESETS
  77. ============================================================================*/
  78. #if (FXAA_QUALITY_PRESET == 10)
  79. #define FXAA_QUALITY_PS 3
  80. #define FXAA_QUALITY_P0 1.5
  81. #define FXAA_QUALITY_P1 3.0
  82. #define FXAA_QUALITY_P2 12.0
  83. #endif
  84. /*--------------------------------------------------------------------------*/
  85. #if (FXAA_QUALITY_PRESET == 11)
  86. #define FXAA_QUALITY_PS 4
  87. #define FXAA_QUALITY_P0 1.0
  88. #define FXAA_QUALITY_P1 1.5
  89. #define FXAA_QUALITY_P2 3.0
  90. #define FXAA_QUALITY_P3 12.0
  91. #endif
  92. /*--------------------------------------------------------------------------*/
  93. #if (FXAA_QUALITY_PRESET == 12)
  94. #define FXAA_QUALITY_PS 5
  95. #define FXAA_QUALITY_P0 1.0
  96. #define FXAA_QUALITY_P1 1.5
  97. #define FXAA_QUALITY_P2 2.0
  98. #define FXAA_QUALITY_P3 4.0
  99. #define FXAA_QUALITY_P4 12.0
  100. #endif
  101. /*--------------------------------------------------------------------------*/
  102. #if (FXAA_QUALITY_PRESET == 13)
  103. #define FXAA_QUALITY_PS 6
  104. #define FXAA_QUALITY_P0 1.0
  105. #define FXAA_QUALITY_P1 1.5
  106. #define FXAA_QUALITY_P2 2.0
  107. #define FXAA_QUALITY_P3 2.0
  108. #define FXAA_QUALITY_P4 4.0
  109. #define FXAA_QUALITY_P5 12.0
  110. #endif
  111. /*--------------------------------------------------------------------------*/
  112. #if (FXAA_QUALITY_PRESET == 14)
  113. #define FXAA_QUALITY_PS 7
  114. #define FXAA_QUALITY_P0 1.0
  115. #define FXAA_QUALITY_P1 1.5
  116. #define FXAA_QUALITY_P2 2.0
  117. #define FXAA_QUALITY_P3 2.0
  118. #define FXAA_QUALITY_P4 2.0
  119. #define FXAA_QUALITY_P5 4.0
  120. #define FXAA_QUALITY_P6 12.0
  121. #endif
  122. /*--------------------------------------------------------------------------*/
  123. #if (FXAA_QUALITY_PRESET == 15)
  124. #define FXAA_QUALITY_PS 8
  125. #define FXAA_QUALITY_P0 1.0
  126. #define FXAA_QUALITY_P1 1.5
  127. #define FXAA_QUALITY_P2 2.0
  128. #define FXAA_QUALITY_P3 2.0
  129. #define FXAA_QUALITY_P4 2.0
  130. #define FXAA_QUALITY_P5 2.0
  131. #define FXAA_QUALITY_P6 4.0
  132. #define FXAA_QUALITY_P7 12.0
  133. #endif
  134. /*============================================================================
  135. FXAA QUALITY - LOW DITHER PRESETS
  136. ============================================================================*/
  137. #if (FXAA_QUALITY_PRESET == 20)
  138. #define FXAA_QUALITY_PS 3
  139. #define FXAA_QUALITY_P0 1.5
  140. #define FXAA_QUALITY_P1 2.0
  141. #define FXAA_QUALITY_P2 8.0
  142. #endif
  143. /*--------------------------------------------------------------------------*/
  144. #if (FXAA_QUALITY_PRESET == 21)
  145. #define FXAA_QUALITY_PS 4
  146. #define FXAA_QUALITY_P0 1.0
  147. #define FXAA_QUALITY_P1 1.5
  148. #define FXAA_QUALITY_P2 2.0
  149. #define FXAA_QUALITY_P3 8.0
  150. #endif
  151. /*--------------------------------------------------------------------------*/
  152. #if (FXAA_QUALITY_PRESET == 22)
  153. #define FXAA_QUALITY_PS 5
  154. #define FXAA_QUALITY_P0 1.0
  155. #define FXAA_QUALITY_P1 1.5
  156. #define FXAA_QUALITY_P2 2.0
  157. #define FXAA_QUALITY_P3 2.0
  158. #define FXAA_QUALITY_P4 8.0
  159. #endif
  160. /*--------------------------------------------------------------------------*/
  161. #if (FXAA_QUALITY_PRESET == 23)
  162. #define FXAA_QUALITY_PS 6
  163. #define FXAA_QUALITY_P0 1.0
  164. #define FXAA_QUALITY_P1 1.5
  165. #define FXAA_QUALITY_P2 2.0
  166. #define FXAA_QUALITY_P3 2.0
  167. #define FXAA_QUALITY_P4 2.0
  168. #define FXAA_QUALITY_P5 8.0
  169. #endif
  170. /*--------------------------------------------------------------------------*/
  171. #if (FXAA_QUALITY_PRESET == 24)
  172. #define FXAA_QUALITY_PS 7
  173. #define FXAA_QUALITY_P0 1.0
  174. #define FXAA_QUALITY_P1 1.5
  175. #define FXAA_QUALITY_P2 2.0
  176. #define FXAA_QUALITY_P3 2.0
  177. #define FXAA_QUALITY_P4 2.0
  178. #define FXAA_QUALITY_P5 3.0
  179. #define FXAA_QUALITY_P6 8.0
  180. #endif
  181. /*--------------------------------------------------------------------------*/
  182. #if (FXAA_QUALITY_PRESET == 25)
  183. #define FXAA_QUALITY_PS 8
  184. #define FXAA_QUALITY_P0 1.0
  185. #define FXAA_QUALITY_P1 1.5
  186. #define FXAA_QUALITY_P2 2.0
  187. #define FXAA_QUALITY_P3 2.0
  188. #define FXAA_QUALITY_P4 2.0
  189. #define FXAA_QUALITY_P5 2.0
  190. #define FXAA_QUALITY_P6 4.0
  191. #define FXAA_QUALITY_P7 8.0
  192. #endif
  193. /*--------------------------------------------------------------------------*/
  194. #if (FXAA_QUALITY_PRESET == 26)
  195. #define FXAA_QUALITY_PS 9
  196. #define FXAA_QUALITY_P0 1.0
  197. #define FXAA_QUALITY_P1 1.5
  198. #define FXAA_QUALITY_P2 2.0
  199. #define FXAA_QUALITY_P3 2.0
  200. #define FXAA_QUALITY_P4 2.0
  201. #define FXAA_QUALITY_P5 2.0
  202. #define FXAA_QUALITY_P6 2.0
  203. #define FXAA_QUALITY_P7 4.0
  204. #define FXAA_QUALITY_P8 8.0
  205. #endif
  206. /*--------------------------------------------------------------------------*/
  207. #if (FXAA_QUALITY_PRESET == 27)
  208. #define FXAA_QUALITY_PS 10
  209. #define FXAA_QUALITY_P0 1.0
  210. #define FXAA_QUALITY_P1 1.5
  211. #define FXAA_QUALITY_P2 2.0
  212. #define FXAA_QUALITY_P3 2.0
  213. #define FXAA_QUALITY_P4 2.0
  214. #define FXAA_QUALITY_P5 2.0
  215. #define FXAA_QUALITY_P6 2.0
  216. #define FXAA_QUALITY_P7 2.0
  217. #define FXAA_QUALITY_P8 4.0
  218. #define FXAA_QUALITY_P9 8.0
  219. #endif
  220. /*--------------------------------------------------------------------------*/
  221. #if (FXAA_QUALITY_PRESET == 28)
  222. #define FXAA_QUALITY_PS 11
  223. #define FXAA_QUALITY_P0 1.0
  224. #define FXAA_QUALITY_P1 1.5
  225. #define FXAA_QUALITY_P2 2.0
  226. #define FXAA_QUALITY_P3 2.0
  227. #define FXAA_QUALITY_P4 2.0
  228. #define FXAA_QUALITY_P5 2.0
  229. #define FXAA_QUALITY_P6 2.0
  230. #define FXAA_QUALITY_P7 2.0
  231. #define FXAA_QUALITY_P8 2.0
  232. #define FXAA_QUALITY_P9 4.0
  233. #define FXAA_QUALITY_P10 8.0
  234. #endif
  235. /*--------------------------------------------------------------------------*/
  236. #if (FXAA_QUALITY_PRESET == 29)
  237. #define FXAA_QUALITY_PS 12
  238. #define FXAA_QUALITY_P0 1.0
  239. #define FXAA_QUALITY_P1 1.5
  240. #define FXAA_QUALITY_P2 2.0
  241. #define FXAA_QUALITY_P3 2.0
  242. #define FXAA_QUALITY_P4 2.0
  243. #define FXAA_QUALITY_P5 2.0
  244. #define FXAA_QUALITY_P6 2.0
  245. #define FXAA_QUALITY_P7 2.0
  246. #define FXAA_QUALITY_P8 2.0
  247. #define FXAA_QUALITY_P9 2.0
  248. #define FXAA_QUALITY_P10 4.0
  249. #define FXAA_QUALITY_P11 8.0
  250. #endif
  251. /*============================================================================
  252. FXAA QUALITY - EXTREME QUALITY
  253. ============================================================================*/
  254. #if (FXAA_QUALITY_PRESET == 39)
  255. #define FXAA_QUALITY_PS 12
  256. #define FXAA_QUALITY_P0 1.0
  257. #define FXAA_QUALITY_P1 1.0
  258. #define FXAA_QUALITY_P2 1.0
  259. #define FXAA_QUALITY_P3 1.0
  260. #define FXAA_QUALITY_P4 1.0
  261. #define FXAA_QUALITY_P5 1.5
  262. #define FXAA_QUALITY_P6 2.0
  263. #define FXAA_QUALITY_P7 2.0
  264. #define FXAA_QUALITY_P8 2.0
  265. #define FXAA_QUALITY_P9 2.0
  266. #define FXAA_QUALITY_P10 4.0
  267. #define FXAA_QUALITY_P11 8.0
  268. #endif
  269. /*============================================================================
  270. Support Functions
  271. ============================================================================*/
  272. float CalcLuma(float3 rgb)
  273. {
  274. float3 luma = float3(0.299, 0.587, 0.114);
  275. return dot(rgb, luma);
  276. }
  277. /*--------------------------------------------------------------------------*/
  278. #define FxaaTexTop(t, p) float4(tex2Dlod(t, float4(p, 0.0, 0.0)).rgb, 1.0)
  279. #define LumaTop(t, p) CalcLuma(tex2Dlod(t, float4(p, 0.0, 0.0)).rgb)
  280. #define LumaOff(t, p, o, r) CalcLuma(tex2Dlod(t, float4(p + (o * r), 0, 0)).rgb)
  281. /*============================================================================
  282. FXAA3 QUALITY - PC
  283. ============================================================================*/
  284. float4 FxaaPixelShader(
  285. //
  286. // Use noperspective interpolation here (turn off perspective interpolation).
  287. // {xy} = center of pixel
  288. float2 pos,
  289. //
  290. // Input color texture.
  291. // {rgb_} = color in linear or perceptual color space
  292. // if (FXAA_GREEN_AS_LUMA == 0)
  293. // {__a} = luma in perceptual color space (not linear)
  294. sampler2D tex,
  295. //
  296. // Only used on FXAA Quality.
  297. // This must be from a constant/uniform.
  298. // {x_} = 1.0/screenWidthInPixels
  299. // {_y} = 1.0/screenHeightInPixels
  300. float2 fxaaQualityRcpFrame,
  301. //
  302. // Only used on FXAA Quality.
  303. // This used to be the FXAA_QUALITY_SUBPIX define.
  304. // It is here now to allow easier tuning.
  305. // Choose the amount of sub-pixel aliasing removal.
  306. // This can effect sharpness.
  307. // 1.00 - upper limit (softer)
  308. // 0.75 - default amount of filtering
  309. // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
  310. // 0.25 - almost off
  311. // 0.00 - completely off
  312. float fxaaQualitySubpix,
  313. //
  314. // Only used on FXAA Quality.
  315. // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define.
  316. // It is here now to allow easier tuning.
  317. // The minimum amount of local contrast required to apply algorithm.
  318. // 0.333 - too little (faster)
  319. // 0.250 - low quality
  320. // 0.166 - default
  321. // 0.125 - high quality
  322. // 0.063 - overkill (slower)
  323. float fxaaQualityEdgeThreshold,
  324. //
  325. // Only used on FXAA Quality.
  326. // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define.
  327. // It is here now to allow easier tuning.
  328. // Trims the algorithm from processing darks.
  329. // 0.0833 - upper limit (default, the start of visible unfiltered edges)
  330. // 0.0625 - high quality (faster)
  331. // 0.0312 - visible limit (slower)
  332. // Special notes when using FXAA_GREEN_AS_LUMA,
  333. // Likely want to set this to zero.
  334. // As colors that are mostly not-green
  335. // will appear very dark in the green channel!
  336. // Tune by looking at mostly non-green content,
  337. // then start at zero and increase until aliasing is a problem.
  338. float fxaaQualityEdgeThresholdMin
  339. ) {
  340. /*--------------------------------------------------------------------------*/
  341. float2 posM;
  342. posM.x = pos.x;
  343. posM.y = pos.y;
  344. float4 rgbyM = FxaaTexTop(tex, posM);
  345. rgbyM.y = CalcLuma(rgbyM.rgb);
  346. #define lumaM rgbyM.y
  347. float lumaS = LumaOff(tex, posM, float2( 0, 1), fxaaQualityRcpFrame.xy);
  348. float lumaE = LumaOff(tex, posM, float2( 1, 0), fxaaQualityRcpFrame.xy);
  349. float lumaN = LumaOff(tex, posM, float2( 0,-1), fxaaQualityRcpFrame.xy);
  350. float lumaW = LumaOff(tex, posM, float2(-1, 0), fxaaQualityRcpFrame.xy);
  351. /*--------------------------------------------------------------------------*/
  352. float maxSM = max(lumaS, lumaM);
  353. float minSM = min(lumaS, lumaM);
  354. float maxESM = max(lumaE, maxSM);
  355. float minESM = min(lumaE, minSM);
  356. float maxWN = max(lumaN, lumaW);
  357. float minWN = min(lumaN, lumaW);
  358. float rangeMax = max(maxWN, maxESM);
  359. float rangeMin = min(minWN, minESM);
  360. float rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
  361. float range = rangeMax - rangeMin;
  362. float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
  363. bool earlyExit = range < rangeMaxClamped;
  364. /*--------------------------------------------------------------------------*/
  365. if(earlyExit)
  366. return FxaaTexTop(tex, pos);
  367. /*--------------------------------------------------------------------------*/
  368. float lumaNW = LumaOff(tex, posM, float2(-1,-1), fxaaQualityRcpFrame.xy);
  369. float lumaSE = LumaOff(tex, posM, float2( 1, 1), fxaaQualityRcpFrame.xy);
  370. float lumaNE = LumaOff(tex, posM, float2( 1,-1), fxaaQualityRcpFrame.xy);
  371. float lumaSW = LumaOff(tex, posM, float2(-1, 1), fxaaQualityRcpFrame.xy);
  372. /*--------------------------------------------------------------------------*/
  373. float lumaNS = lumaN + lumaS;
  374. float lumaWE = lumaW + lumaE;
  375. float subpixRcpRange = 1.0/range;
  376. float subpixNSWE = lumaNS + lumaWE;
  377. float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
  378. float edgeVert1 = (-2.0 * lumaM) + lumaWE;
  379. /*--------------------------------------------------------------------------*/
  380. float lumaNESE = lumaNE + lumaSE;
  381. float lumaNWNE = lumaNW + lumaNE;
  382. float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
  383. float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
  384. /*--------------------------------------------------------------------------*/
  385. float lumaNWSW = lumaNW + lumaSW;
  386. float lumaSWSE = lumaSW + lumaSE;
  387. float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
  388. float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
  389. float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
  390. float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
  391. float edgeHorz = abs(edgeHorz3) + edgeHorz4;
  392. float edgeVert = abs(edgeVert3) + edgeVert4;
  393. /*--------------------------------------------------------------------------*/
  394. float subpixNWSWNESE = lumaNWSW + lumaNESE;
  395. float lengthSign = fxaaQualityRcpFrame.x;
  396. bool horzSpan = edgeHorz >= edgeVert;
  397. float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
  398. /*--------------------------------------------------------------------------*/
  399. if(!horzSpan) lumaN = lumaW;
  400. if(!horzSpan) lumaS = lumaE;
  401. if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
  402. float subpixB = (subpixA * (1.0/12.0)) - lumaM;
  403. /*--------------------------------------------------------------------------*/
  404. float gradientN = lumaN - lumaM;
  405. float gradientS = lumaS - lumaM;
  406. float lumaNN = lumaN + lumaM;
  407. float lumaSS = lumaS + lumaM;
  408. bool pairN = abs(gradientN) >= abs(gradientS);
  409. float gradient = max(abs(gradientN), abs(gradientS));
  410. if(pairN) lengthSign = -lengthSign;
  411. float subpixC = clamp((abs(subpixB) * subpixRcpRange), 0.0, 1.0);
  412. /*--------------------------------------------------------------------------*/
  413. float2 posB;
  414. posB.x = posM.x;
  415. posB.y = posM.y;
  416. float2 offNP;
  417. offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
  418. offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
  419. if(!horzSpan) posB.x += lengthSign * 0.5;
  420. if( horzSpan) posB.y += lengthSign * 0.5;
  421. /*--------------------------------------------------------------------------*/
  422. float2 posN;
  423. posN.x = posB.x - offNP.x * FXAA_QUALITY_P0;
  424. posN.y = posB.y - offNP.y * FXAA_QUALITY_P0;
  425. float2 posP;
  426. posP.x = posB.x + offNP.x * FXAA_QUALITY_P0;
  427. posP.y = posB.y + offNP.y * FXAA_QUALITY_P0;
  428. float subpixD = ((-2.0)*subpixC) + 3.0;
  429. float lumaEndN = LumaTop(tex, posN);
  430. float subpixE = subpixC * subpixC;
  431. float lumaEndP = LumaTop(tex, posP);
  432. /*--------------------------------------------------------------------------*/
  433. if(!pairN) lumaNN = lumaSS;
  434. float gradientScaled = gradient * 1.0/4.0;
  435. float lumaMM = lumaM - lumaNN * 0.5;
  436. float subpixF = subpixD * subpixE;
  437. bool lumaMLTZero = lumaMM < 0.0;
  438. /*--------------------------------------------------------------------------*/
  439. lumaEndN -= lumaNN * 0.5;
  440. lumaEndP -= lumaNN * 0.5;
  441. bool doneN = abs(lumaEndN) >= gradientScaled;
  442. bool doneP = abs(lumaEndP) >= gradientScaled;
  443. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1;
  444. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1;
  445. bool doneNP = (!doneN) || (!doneP);
  446. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1;
  447. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1;
  448. /*--------------------------------------------------------------------------*/
  449. if(doneNP) {
  450. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  451. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  452. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  453. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  454. doneN = abs(lumaEndN) >= gradientScaled;
  455. doneP = abs(lumaEndP) >= gradientScaled;
  456. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P2;
  457. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2;
  458. doneNP = (!doneN) || (!doneP);
  459. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2;
  460. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2;
  461. /*--------------------------------------------------------------------------*/
  462. #if (FXAA_QUALITY_PS > 3)
  463. if(doneNP) {
  464. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  465. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  466. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  467. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  468. doneN = abs(lumaEndN) >= gradientScaled;
  469. doneP = abs(lumaEndP) >= gradientScaled;
  470. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P3;
  471. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3;
  472. doneNP = (!doneN) || (!doneP);
  473. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3;
  474. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3;
  475. /*--------------------------------------------------------------------------*/
  476. #if (FXAA_QUALITY_PS > 4)
  477. if(doneNP) {
  478. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  479. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  480. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  481. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  482. doneN = abs(lumaEndN) >= gradientScaled;
  483. doneP = abs(lumaEndP) >= gradientScaled;
  484. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P4;
  485. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4;
  486. doneNP = (!doneN) || (!doneP);
  487. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4;
  488. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4;
  489. /*--------------------------------------------------------------------------*/
  490. #if (FXAA_QUALITY_PS > 5)
  491. if(doneNP) {
  492. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  493. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  494. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  495. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  496. doneN = abs(lumaEndN) >= gradientScaled;
  497. doneP = abs(lumaEndP) >= gradientScaled;
  498. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P5;
  499. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5;
  500. doneNP = (!doneN) || (!doneP);
  501. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5;
  502. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5;
  503. /*--------------------------------------------------------------------------*/
  504. #if (FXAA_QUALITY_PS > 6)
  505. if(doneNP) {
  506. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  507. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  508. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  509. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  510. doneN = abs(lumaEndN) >= gradientScaled;
  511. doneP = abs(lumaEndP) >= gradientScaled;
  512. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P6;
  513. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6;
  514. doneNP = (!doneN) || (!doneP);
  515. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6;
  516. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6;
  517. /*--------------------------------------------------------------------------*/
  518. #if (FXAA_QUALITY_PS > 7)
  519. if(doneNP) {
  520. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  521. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  522. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  523. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  524. doneN = abs(lumaEndN) >= gradientScaled;
  525. doneP = abs(lumaEndP) >= gradientScaled;
  526. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P7;
  527. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7;
  528. doneNP = (!doneN) || (!doneP);
  529. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7;
  530. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7;
  531. /*--------------------------------------------------------------------------*/
  532. #if (FXAA_QUALITY_PS > 8)
  533. if(doneNP) {
  534. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  535. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  536. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  537. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  538. doneN = abs(lumaEndN) >= gradientScaled;
  539. doneP = abs(lumaEndP) >= gradientScaled;
  540. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P8;
  541. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8;
  542. doneNP = (!doneN) || (!doneP);
  543. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8;
  544. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8;
  545. /*--------------------------------------------------------------------------*/
  546. #if (FXAA_QUALITY_PS > 9)
  547. if(doneNP) {
  548. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  549. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  550. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  551. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  552. doneN = abs(lumaEndN) >= gradientScaled;
  553. doneP = abs(lumaEndP) >= gradientScaled;
  554. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9;
  555. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9;
  556. doneNP = (!doneN) || (!doneP);
  557. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9;
  558. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9;
  559. /*--------------------------------------------------------------------------*/
  560. #if (FXAA_QUALITY_PS > 10)
  561. if(doneNP) {
  562. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  563. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  564. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  565. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  566. doneN = abs(lumaEndN) >= gradientScaled;
  567. doneP = abs(lumaEndP) >= gradientScaled;
  568. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10;
  569. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10;
  570. doneNP = (!doneN) || (!doneP);
  571. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10;
  572. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10;
  573. /*--------------------------------------------------------------------------*/
  574. #if (FXAA_QUALITY_PS > 11)
  575. if(doneNP) {
  576. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  577. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  578. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  579. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  580. doneN = abs(lumaEndN) >= gradientScaled;
  581. doneP = abs(lumaEndP) >= gradientScaled;
  582. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11;
  583. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11;
  584. doneNP = (!doneN) || (!doneP);
  585. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11;
  586. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11;
  587. /*--------------------------------------------------------------------------*/
  588. #if (FXAA_QUALITY_PS > 12)
  589. if(doneNP) {
  590. if(!doneN) lumaEndN = LumaTop(tex, posN.xy);
  591. if(!doneP) lumaEndP = LumaTop(tex, posP.xy);
  592. if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
  593. if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
  594. doneN = abs(lumaEndN) >= gradientScaled;
  595. doneP = abs(lumaEndP) >= gradientScaled;
  596. if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12;
  597. if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12;
  598. doneNP = (!doneN) || (!doneP);
  599. if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12;
  600. if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12;
  601. /*--------------------------------------------------------------------------*/
  602. }
  603. #endif
  604. /*--------------------------------------------------------------------------*/
  605. }
  606. #endif
  607. /*--------------------------------------------------------------------------*/
  608. }
  609. #endif
  610. /*--------------------------------------------------------------------------*/
  611. }
  612. #endif
  613. /*--------------------------------------------------------------------------*/
  614. }
  615. #endif
  616. /*--------------------------------------------------------------------------*/
  617. }
  618. #endif
  619. /*--------------------------------------------------------------------------*/
  620. }
  621. #endif
  622. /*--------------------------------------------------------------------------*/
  623. }
  624. #endif
  625. /*--------------------------------------------------------------------------*/
  626. }
  627. #endif
  628. /*--------------------------------------------------------------------------*/
  629. }
  630. #endif
  631. /*--------------------------------------------------------------------------*/
  632. }
  633. /*--------------------------------------------------------------------------*/
  634. float dstN = posM.x - posN.x;
  635. float dstP = posP.x - posM.x;
  636. if(!horzSpan) dstN = posM.y - posN.y;
  637. if(!horzSpan) dstP = posP.y - posM.y;
  638. /*--------------------------------------------------------------------------*/
  639. bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
  640. float spanLength = (dstP + dstN);
  641. bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
  642. float spanLengthRcp = 1.0/spanLength;
  643. /*--------------------------------------------------------------------------*/
  644. bool directionN = dstN < dstP;
  645. float dst = min(dstN, dstP);
  646. bool goodSpan = directionN ? goodSpanN : goodSpanP;
  647. float subpixG = subpixF * subpixF;
  648. float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
  649. float subpixH = subpixG * fxaaQualitySubpix;
  650. /*--------------------------------------------------------------------------*/
  651. float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
  652. float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
  653. if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
  654. if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
  655. return FxaaTexTop(tex, posM);
  656. }
  657. /*==========================================================================*/
  658. /*============================================================================
  659. Urho3D Vertex- and Pixelshader
  660. ============================================================================*/
  661. void VS(float4 iPos : POSITION,
  662. out float4 oPos : POSITION,
  663. out float2 oScreenPos : TEXCOORD0)
  664. {
  665. float4x3 modelMatrix = iModelMatrix;
  666. float3 worldPos = GetWorldPos(modelMatrix);
  667. oPos = GetClipPos(worldPos);
  668. oScreenPos = GetScreenPosPreDiv(oPos);
  669. }
  670. void PS(float2 iScreenPos : TEXCOORD0,
  671. out float4 oColor : COLOR0)
  672. {
  673. float2 rcpFrame = float2(cGBufferInvSize.x, cGBufferInvSize.y);
  674. oColor = FxaaPixelShader(
  675. iScreenPos, // float2 pos,
  676. sDiffMap, // sampler2D tex,
  677. rcpFrame, // float2 fxaaQualityRcpFrame,
  678. 0.75f, // float fxaaQualitySubpix,
  679. 0.166f, // float fxaaQualityEdgeThreshold,
  680. 0.0833f // float fxaaQualityEdgeThresholdMin
  681. );
  682. }