1
2//
3
4#define FXAA_GREEN_AS_LUMA 1  // TODO: pack luma into alpha
5#define FXAA_GLSL_120 1
6#define FXAA_PC 1
7#define FXAA_QUALITY__PRESET 39
8#define FXAA_GATHER4_ALPHA 0
9
10#define texture2DLod(s,v,f) texture(s,v)
11
12#define FXAA_FAST_PIXEL_OFFSET 0
13    // At least one Intel GPU on Linux does not define texture2DLodOffset when GL_ARB_gpu_shader5 is
14    // enabled. FXAA checks for GL_*_gpu_shader5 to use texture2DLodOffset but it seems like it's
15    // only officially supported for shader4.
16
17/*============================================================================
18
19                             INTEGRATION KNOBS
20
21============================================================================*/
22//
23// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).
24// FXAA_360_OPT is a prototype for the new optimized 360 version.
25//
26// 1 = Use API.
27// 0 = Don't use API.
28//
29/*--------------------------------------------------------------------------*/
30#ifndef FXAA_PS3
31    #define FXAA_PS3 0
32#endif
33/*--------------------------------------------------------------------------*/
34#ifndef FXAA_360
35    #define FXAA_360 0
36#endif
37/*--------------------------------------------------------------------------*/
38#ifndef FXAA_360_OPT
39    #define FXAA_360_OPT 0
40#endif
41/*==========================================================================*/
42#ifndef FXAA_PC
43    //
44    // FXAA Quality
45    // The high quality PC algorithm.
46    //
47    #define FXAA_PC 0
48#endif
49/*--------------------------------------------------------------------------*/
50#ifndef FXAA_PC_CONSOLE
51    //
52    // The console algorithm for PC is included
53    // for developers targeting really low spec machines.
54    // Likely better to just run FXAA_PC, and use a really low preset.
55    //
56    #define FXAA_PC_CONSOLE 0
57#endif
58/*--------------------------------------------------------------------------*/
59#ifndef FXAA_GLSL_120
60    #define FXAA_GLSL_120 0
61#endif
62/*--------------------------------------------------------------------------*/
63#ifndef FXAA_GLSL_130
64    #define FXAA_GLSL_130 0
65#endif
66/*--------------------------------------------------------------------------*/
67#ifndef FXAA_HLSL_3
68    #define FXAA_HLSL_3 0
69#endif
70/*--------------------------------------------------------------------------*/
71#ifndef FXAA_HLSL_4
72    #define FXAA_HLSL_4 0
73#endif
74/*--------------------------------------------------------------------------*/
75#ifndef FXAA_HLSL_5
76    #define FXAA_HLSL_5 0
77#endif
78/*==========================================================================*/
79#ifndef FXAA_GREEN_AS_LUMA
80    //
81    // For those using non-linear color,
82    // and either not able to get luma in alpha, or not wanting to,
83    // this enables FXAA to run using green as a proxy for luma.
84    // So with this enabled, no need to pack luma in alpha.
85    //
86    // This will turn off AA on anything which lacks some amount of green.
87    // Pure red and blue or combination of only R and B, will get no AA.
88    //
89    // Might want to lower the settings for both,
90    //    fxaaConsoleEdgeThresholdMin
91    //    fxaaQualityEdgeThresholdMin
92    // In order to insure AA does not get turned off on colors
93    // which contain a minor amount of green.
94    //
95    // 1 = On.
96    // 0 = Off.
97    //
98    #define FXAA_GREEN_AS_LUMA 0
99#endif
100/*--------------------------------------------------------------------------*/
101#ifndef FXAA_EARLY_EXIT
102    //
103    // Controls algorithm's early exit path.
104    // On PS3 turning this ON adds 2 cycles to the shader.
105    // On 360 turning this OFF adds 10ths of a millisecond to the shader.
106    // Turning this off on console will result in a more blurry image.
107    // So this defaults to on.
108    //
109    // 1 = On.
110    // 0 = Off.
111    //
112    #define FXAA_EARLY_EXIT 1
113#endif
114/*--------------------------------------------------------------------------*/
115#ifndef FXAA_DISCARD
116    //
117    // Only valid for PC OpenGL currently.
118    // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
119    //
120    // 1 = Use discard on pixels which don't need AA.
121    //     For APIs which enable concurrent TEX+ROP from same surface.
122    // 0 = Return unchanged color on pixels which don't need AA.
123    //
124    #define FXAA_DISCARD 0
125#endif
126/*--------------------------------------------------------------------------*/
127#ifndef FXAA_FAST_PIXEL_OFFSET
128    //
129    // Used for GLSL 120 only.
130    //
131    // 1 = GL API supports fast pixel offsets
132    // 0 = do not use fast pixel offsets
133    //
134    #ifdef GL_EXT_gpu_shader4
135        #define FXAA_FAST_PIXEL_OFFSET 1
136    #endif
137    #ifdef GL_NV_gpu_shader5
138        #define FXAA_FAST_PIXEL_OFFSET 1
139    #endif
140    #ifdef GL_ARB_gpu_shader5
141        #define FXAA_FAST_PIXEL_OFFSET 1
142    #endif
143    #ifndef FXAA_FAST_PIXEL_OFFSET
144        #define FXAA_FAST_PIXEL_OFFSET 0
145    #endif
146#endif
147/*--------------------------------------------------------------------------*/
148#ifndef FXAA_GATHER4_ALPHA
149    //
150    // 1 = API supports gather4 on alpha channel.
151    // 0 = API does not support gather4 on alpha channel.
152    //
153    #if (FXAA_HLSL_5 == 1)
154        #define FXAA_GATHER4_ALPHA 1
155    #endif
156    #ifdef GL_ARB_gpu_shader5
157        #define FXAA_GATHER4_ALPHA 1
158    #endif
159    #ifdef GL_NV_gpu_shader5
160        #define FXAA_GATHER4_ALPHA 1
161    #endif
162    #ifndef FXAA_GATHER4_ALPHA
163        #define FXAA_GATHER4_ALPHA 0
164    #endif
165#endif
166
167/*============================================================================
168                      FXAA CONSOLE PS3 - TUNING KNOBS
169============================================================================*/
170#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS
171    //
172    // Consoles the sharpness of edges on PS3 only.
173    // Non-PS3 tuning is done with shader input.
174    //
175    // Due to the PS3 being ALU bound,
176    // there are only two safe values here: 4 and 8.
177    // These options use the shaders ability to a free *|/ by 2|4|8.
178    //
179    // 8.0 is sharper
180    // 4.0 is softer
181    // 2.0 is really soft (good for vector graphics inputs)
182    //
183    #if 1
184        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
185    #endif
186    #if 0
187        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
188    #endif
189    #if 0
190        #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
191    #endif
192#endif
193/*--------------------------------------------------------------------------*/
194#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD
195    //
196    // Only effects PS3.
197    // Non-PS3 tuning is done with shader input.
198    //
199    // The minimum amount of local contrast required to apply algorithm.
200    // The console setting has a different mapping than the quality setting.
201    //
202    // This only applies when FXAA_EARLY_EXIT is 1.
203    //
204    // Due to the PS3 being ALU bound,
205    // there are only two safe values here: 0.25 and 0.125.
206    // These options use the shaders ability to a free *|/ by 2|4|8.
207    //
208    // 0.125 leaves less aliasing, but is softer
209    // 0.25 leaves more aliasing, and is sharper
210    //
211    #if 1
212        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
213    #else
214        #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
215    #endif
216#endif
217
218/*============================================================================
219                        FXAA QUALITY - TUNING KNOBS
220------------------------------------------------------------------------------
221NOTE the other tuning knobs are now in the shader function inputs!
222============================================================================*/
223#ifndef FXAA_QUALITY__PRESET
224    //
225    // Choose the quality preset.
226    // This needs to be compiled into the shader as it effects code.
227    // Best option to include multiple presets is to
228    // in each shader define the preset, then include this file.
229    //
230    // OPTIONS
231    // -----------------------------------------------------------------------
232    // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
233    // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
234    // 39       - no dither, very expensive
235    //
236    // NOTES
237    // -----------------------------------------------------------------------
238    // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
239    // 13 = about same speed as FXAA 3.9 and better than 12
240    // 23 = closest to FXAA 3.9 visually and performance wise
241    //  _ = the lowest digit is directly related to performance
242    // _  = the highest digit is directly related to style
243    //
244    #define FXAA_QUALITY__PRESET 12
245#endif
246
247
248/*============================================================================
249
250                           FXAA QUALITY - PRESETS
251
252============================================================================*/
253
254/*============================================================================
255                     FXAA QUALITY - MEDIUM DITHER PRESETS
256============================================================================*/
257#if (FXAA_QUALITY__PRESET == 10)
258    #define FXAA_QUALITY__PS 3
259    #define FXAA_QUALITY__P0 1.5
260    #define FXAA_QUALITY__P1 3.0
261    #define FXAA_QUALITY__P2 12.0
262#endif
263/*--------------------------------------------------------------------------*/
264#if (FXAA_QUALITY__PRESET == 11)
265    #define FXAA_QUALITY__PS 4
266    #define FXAA_QUALITY__P0 1.0
267    #define FXAA_QUALITY__P1 1.5
268    #define FXAA_QUALITY__P2 3.0
269    #define FXAA_QUALITY__P3 12.0
270#endif
271/*--------------------------------------------------------------------------*/
272#if (FXAA_QUALITY__PRESET == 12)
273    #define FXAA_QUALITY__PS 5
274    #define FXAA_QUALITY__P0 1.0
275    #define FXAA_QUALITY__P1 1.5
276    #define FXAA_QUALITY__P2 2.0
277    #define FXAA_QUALITY__P3 4.0
278    #define FXAA_QUALITY__P4 12.0
279#endif
280/*--------------------------------------------------------------------------*/
281#if (FXAA_QUALITY__PRESET == 13)
282    #define FXAA_QUALITY__PS 6
283    #define FXAA_QUALITY__P0 1.0
284    #define FXAA_QUALITY__P1 1.5
285    #define FXAA_QUALITY__P2 2.0
286    #define FXAA_QUALITY__P3 2.0
287    #define FXAA_QUALITY__P4 4.0
288    #define FXAA_QUALITY__P5 12.0
289#endif
290/*--------------------------------------------------------------------------*/
291#if (FXAA_QUALITY__PRESET == 14)
292    #define FXAA_QUALITY__PS 7
293    #define FXAA_QUALITY__P0 1.0
294    #define FXAA_QUALITY__P1 1.5
295    #define FXAA_QUALITY__P2 2.0
296    #define FXAA_QUALITY__P3 2.0
297    #define FXAA_QUALITY__P4 2.0
298    #define FXAA_QUALITY__P5 4.0
299    #define FXAA_QUALITY__P6 12.0
300#endif
301/*--------------------------------------------------------------------------*/
302#if (FXAA_QUALITY__PRESET == 15)
303    #define FXAA_QUALITY__PS 8
304    #define FXAA_QUALITY__P0 1.0
305    #define FXAA_QUALITY__P1 1.5
306    #define FXAA_QUALITY__P2 2.0
307    #define FXAA_QUALITY__P3 2.0
308    #define FXAA_QUALITY__P4 2.0
309    #define FXAA_QUALITY__P5 2.0
310    #define FXAA_QUALITY__P6 4.0
311    #define FXAA_QUALITY__P7 12.0
312#endif
313
314/*============================================================================
315                     FXAA QUALITY - LOW DITHER PRESETS
316============================================================================*/
317#if (FXAA_QUALITY__PRESET == 20)
318    #define FXAA_QUALITY__PS 3
319    #define FXAA_QUALITY__P0 1.5
320    #define FXAA_QUALITY__P1 2.0
321    #define FXAA_QUALITY__P2 8.0
322#endif
323/*--------------------------------------------------------------------------*/
324#if (FXAA_QUALITY__PRESET == 21)
325    #define FXAA_QUALITY__PS 4
326    #define FXAA_QUALITY__P0 1.0
327    #define FXAA_QUALITY__P1 1.5
328    #define FXAA_QUALITY__P2 2.0
329    #define FXAA_QUALITY__P3 8.0
330#endif
331/*--------------------------------------------------------------------------*/
332#if (FXAA_QUALITY__PRESET == 22)
333    #define FXAA_QUALITY__PS 5
334    #define FXAA_QUALITY__P0 1.0
335    #define FXAA_QUALITY__P1 1.5
336    #define FXAA_QUALITY__P2 2.0
337    #define FXAA_QUALITY__P3 2.0
338    #define FXAA_QUALITY__P4 8.0
339#endif
340/*--------------------------------------------------------------------------*/
341#if (FXAA_QUALITY__PRESET == 23)
342    #define FXAA_QUALITY__PS 6
343    #define FXAA_QUALITY__P0 1.0
344    #define FXAA_QUALITY__P1 1.5
345    #define FXAA_QUALITY__P2 2.0
346    #define FXAA_QUALITY__P3 2.0
347    #define FXAA_QUALITY__P4 2.0
348    #define FXAA_QUALITY__P5 8.0
349#endif
350/*--------------------------------------------------------------------------*/
351#if (FXAA_QUALITY__PRESET == 24)
352    #define FXAA_QUALITY__PS 7
353    #define FXAA_QUALITY__P0 1.0
354    #define FXAA_QUALITY__P1 1.5
355    #define FXAA_QUALITY__P2 2.0
356    #define FXAA_QUALITY__P3 2.0
357    #define FXAA_QUALITY__P4 2.0
358    #define FXAA_QUALITY__P5 3.0
359    #define FXAA_QUALITY__P6 8.0
360#endif
361/*--------------------------------------------------------------------------*/
362#if (FXAA_QUALITY__PRESET == 25)
363    #define FXAA_QUALITY__PS 8
364    #define FXAA_QUALITY__P0 1.0
365    #define FXAA_QUALITY__P1 1.5
366    #define FXAA_QUALITY__P2 2.0
367    #define FXAA_QUALITY__P3 2.0
368    #define FXAA_QUALITY__P4 2.0
369    #define FXAA_QUALITY__P5 2.0
370    #define FXAA_QUALITY__P6 4.0
371    #define FXAA_QUALITY__P7 8.0
372#endif
373/*--------------------------------------------------------------------------*/
374#if (FXAA_QUALITY__PRESET == 26)
375    #define FXAA_QUALITY__PS 9
376    #define FXAA_QUALITY__P0 1.0
377    #define FXAA_QUALITY__P1 1.5
378    #define FXAA_QUALITY__P2 2.0
379    #define FXAA_QUALITY__P3 2.0
380    #define FXAA_QUALITY__P4 2.0
381    #define FXAA_QUALITY__P5 2.0
382    #define FXAA_QUALITY__P6 2.0
383    #define FXAA_QUALITY__P7 4.0
384    #define FXAA_QUALITY__P8 8.0
385#endif
386/*--------------------------------------------------------------------------*/
387#if (FXAA_QUALITY__PRESET == 27)
388    #define FXAA_QUALITY__PS 10
389    #define FXAA_QUALITY__P0 1.0
390    #define FXAA_QUALITY__P1 1.5
391    #define FXAA_QUALITY__P2 2.0
392    #define FXAA_QUALITY__P3 2.0
393    #define FXAA_QUALITY__P4 2.0
394    #define FXAA_QUALITY__P5 2.0
395    #define FXAA_QUALITY__P6 2.0
396    #define FXAA_QUALITY__P7 2.0
397    #define FXAA_QUALITY__P8 4.0
398    #define FXAA_QUALITY__P9 8.0
399#endif
400/*--------------------------------------------------------------------------*/
401#if (FXAA_QUALITY__PRESET == 28)
402    #define FXAA_QUALITY__PS 11
403    #define FXAA_QUALITY__P0 1.0
404    #define FXAA_QUALITY__P1 1.5
405    #define FXAA_QUALITY__P2 2.0
406    #define FXAA_QUALITY__P3 2.0
407    #define FXAA_QUALITY__P4 2.0
408    #define FXAA_QUALITY__P5 2.0
409    #define FXAA_QUALITY__P6 2.0
410    #define FXAA_QUALITY__P7 2.0
411    #define FXAA_QUALITY__P8 2.0
412    #define FXAA_QUALITY__P9 4.0
413    #define FXAA_QUALITY__P10 8.0
414#endif
415/*--------------------------------------------------------------------------*/
416#if (FXAA_QUALITY__PRESET == 29)
417    #define FXAA_QUALITY__PS 12
418    #define FXAA_QUALITY__P0 1.0
419    #define FXAA_QUALITY__P1 1.5
420    #define FXAA_QUALITY__P2 2.0
421    #define FXAA_QUALITY__P3 2.0
422    #define FXAA_QUALITY__P4 2.0
423    #define FXAA_QUALITY__P5 2.0
424    #define FXAA_QUALITY__P6 2.0
425    #define FXAA_QUALITY__P7 2.0
426    #define FXAA_QUALITY__P8 2.0
427    #define FXAA_QUALITY__P9 2.0
428    #define FXAA_QUALITY__P10 4.0
429    #define FXAA_QUALITY__P11 8.0
430#endif
431
432/*============================================================================
433                     FXAA QUALITY - EXTREME QUALITY
434============================================================================*/
435#if (FXAA_QUALITY__PRESET == 39)
436    #define FXAA_QUALITY__PS 12
437    #define FXAA_QUALITY__P0 1.0
438    #define FXAA_QUALITY__P1 1.0
439    #define FXAA_QUALITY__P2 1.0
440    #define FXAA_QUALITY__P3 1.0
441    #define FXAA_QUALITY__P4 1.0
442    #define FXAA_QUALITY__P5 1.5
443    #define FXAA_QUALITY__P6 2.0
444    #define FXAA_QUALITY__P7 2.0
445    #define FXAA_QUALITY__P8 2.0
446    #define FXAA_QUALITY__P9 2.0
447    #define FXAA_QUALITY__P10 4.0
448    #define FXAA_QUALITY__P11 8.0
449#endif
450
451
452
453/*============================================================================
454
455                                API PORTING
456
457============================================================================*/
458#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
459    #define FxaaBool bool
460    #define FxaaDiscard discard
461    #define FxaaFloat float
462    #define FxaaFloat2 vec2
463    #define FxaaFloat3 vec3
464    #define FxaaFloat4 vec4
465    #define FxaaHalf float
466    #define FxaaHalf2 vec2
467    #define FxaaHalf3 vec3
468    #define FxaaHalf4 vec4
469    #define FxaaInt2 ivec2
470    #define FxaaSat(x) clamp(x, 0.0, 1.0)
471    #define FxaaTex sampler2D
472#else
473    #define FxaaBool bool
474    #define FxaaDiscard clip(-1)
475    #define FxaaFloat float
476    #define FxaaFloat2 float2
477    #define FxaaFloat3 float3
478    #define FxaaFloat4 float4
479    #define FxaaHalf half
480    #define FxaaHalf2 half2
481    #define FxaaHalf3 half3
482    #define FxaaHalf4 half4
483    #define FxaaSat(x) saturate(x)
484#endif
485/*--------------------------------------------------------------------------*/
486#if (FXAA_GLSL_120 == 1)
487    // Requires,
488    //  #version 120
489    // And at least,
490    //  #extension GL_EXT_gpu_shader4 : enable
491    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
492    #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
493    #if (FXAA_FAST_PIXEL_OFFSET == 1)
494        #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
495    #else
496        #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
497    #endif
498    #if (FXAA_GATHER4_ALPHA == 1)
499        // use #extension GL_ARB_gpu_shader5 : enable
500        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
501        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
502        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
503        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
504    #endif
505#endif
506/*--------------------------------------------------------------------------*/
507#if (FXAA_GLSL_130 == 1)
508    // Requires "#version 130" or better
509    #define FxaaTexTop(t, p) textureLod(t, p, 0.0)
510    #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
511    #if (FXAA_GATHER4_ALPHA == 1)
512        // use #extension GL_ARB_gpu_shader5 : enable
513        #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
514        #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
515        #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
516        #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
517    #endif
518#endif
519/*--------------------------------------------------------------------------*/
520#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
521    #define FxaaInt2 float2
522    #define FxaaTex sampler2D
523    #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
524    #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
525#endif
526/*--------------------------------------------------------------------------*/
527#if (FXAA_HLSL_4 == 1)
528    #define FxaaInt2 int2
529    struct FxaaTex { SamplerState smpl; Texture2D tex; };
530    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
531    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
532#endif
533/*--------------------------------------------------------------------------*/
534#if (FXAA_HLSL_5 == 1)
535    #define FxaaInt2 int2
536    struct FxaaTex { SamplerState smpl; Texture2D tex; };
537    #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
538    #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
539    #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
540    #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
541    #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
542    #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
543#endif
544
545
546/*============================================================================
547                   GREEN AS LUMA OPTION SUPPORT FUNCTION
548============================================================================*/
549#if (FXAA_GREEN_AS_LUMA == 0)
550    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
551#else
552    FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
553#endif
554
555
556
557
558/*============================================================================
559
560                             FXAA3 QUALITY - PC
561
562============================================================================*/
563#if (FXAA_PC == 1)
564/*--------------------------------------------------------------------------*/
565FxaaFloat4 FxaaPixelShader(
566    //
567    // Use noperspective interpolation here (turn off perspective interpolation).
568    // {xy} = center of pixel
569    FxaaFloat2 pos,
570    //
571    // Used only for FXAA Console, and not used on the 360 version.
572    // Use noperspective interpolation here (turn off perspective interpolation).
573    // {xy__} = upper left of pixel
574    // {__zw} = lower right of pixel
575    FxaaFloat4 fxaaConsolePosPos,
576    //
577    // Input color texture.
578    // {rgb_} = color in linear or perceptual color space
579    // if (FXAA_GREEN_AS_LUMA == 0)
580    //     {___a} = luma in perceptual color space (not linear)
581    FxaaTex tex,
582    //
583    // Only used on the optimized 360 version of FXAA Console.
584    // For everything but 360, just use the same input here as for "tex".
585    // For 360, same texture, just alias with a 2nd sampler.
586    // This sampler needs to have an exponent bias of -1.
587    FxaaTex fxaaConsole360TexExpBiasNegOne,
588    //
589    // Only used on the optimized 360 version of FXAA Console.
590    // For everything but 360, just use the same input here as for "tex".
591    // For 360, same texture, just alias with a 3nd sampler.
592    // This sampler needs to have an exponent bias of -2.
593    FxaaTex fxaaConsole360TexExpBiasNegTwo,
594    //
595    // Only used on FXAA Quality.
596    // This must be from a constant/uniform.
597    // {x_} = 1.0/screenWidthInPixels
598    // {_y} = 1.0/screenHeightInPixels
599    FxaaFloat2 fxaaQualityRcpFrame,
600    //
601    // Only used on FXAA Console.
602    // This must be from a constant/uniform.
603    // This effects sub-pixel AA quality and inversely sharpness.
604    //   Where N ranges between,
605    //     N = 0.50 (default)
606    //     N = 0.33 (sharper)
607    // {x___} = -N/screenWidthInPixels
608    // {_y__} = -N/screenHeightInPixels
609    // {__z_} =  N/screenWidthInPixels
610    // {___w} =  N/screenHeightInPixels
611    FxaaFloat4 fxaaConsoleRcpFrameOpt,
612    //
613    // Only used on FXAA Console.
614    // Not used on 360, but used on PS3 and PC.
615    // This must be from a constant/uniform.
616    // {x___} = -2.0/screenWidthInPixels
617    // {_y__} = -2.0/screenHeightInPixels
618    // {__z_} =  2.0/screenWidthInPixels
619    // {___w} =  2.0/screenHeightInPixels
620    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
621    //
622    // Only used on FXAA Console.
623    // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
624    // This must be from a constant/uniform.
625    // {x___} =  8.0/screenWidthInPixels
626    // {_y__} =  8.0/screenHeightInPixels
627    // {__z_} = -4.0/screenWidthInPixels
628    // {___w} = -4.0/screenHeightInPixels
629    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
630    //
631    // Only used on FXAA Quality.
632    // This used to be the FXAA_QUALITY__SUBPIX define.
633    // It is here now to allow easier tuning.
634    // Choose the amount of sub-pixel aliasing removal.
635    // This can effect sharpness.
636    //   1.00 - upper limit (softer)
637    //   0.75 - default amount of filtering
638    //   0.50 - lower limit (sharper, less sub-pixel aliasing removal)
639    //   0.25 - almost off
640    //   0.00 - completely off
641    FxaaFloat fxaaQualitySubpix,
642    //
643    // Only used on FXAA Quality.
644    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
645    // It is here now to allow easier tuning.
646    // The minimum amount of local contrast required to apply algorithm.
647    //   0.333 - too little (faster)
648    //   0.250 - low quality
649    //   0.166 - default
650    //   0.125 - high quality
651    //   0.063 - overkill (slower)
652    FxaaFloat fxaaQualityEdgeThreshold,
653    //
654    // Only used on FXAA Quality.
655    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
656    // It is here now to allow easier tuning.
657    // Trims the algorithm from processing darks.
658    //   0.0833 - upper limit (default, the start of visible unfiltered edges)
659    //   0.0625 - high quality (faster)
660    //   0.0312 - visible limit (slower)
661    // Special notes when using FXAA_GREEN_AS_LUMA,
662    //   Likely want to set this to zero.
663    //   As colors that are mostly not-green
664    //   will appear very dark in the green channel!
665    //   Tune by looking at mostly non-green content,
666    //   then start at zero and increase until aliasing is a problem.
667    FxaaFloat fxaaQualityEdgeThresholdMin,
668    //
669    // Only used on FXAA Console.
670    // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
671    // It is here now to allow easier tuning.
672    // This does not effect PS3, as this needs to be compiled in.
673    //   Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
674    //   Due to the PS3 being ALU bound,
675    //   there are only three safe values here: 2 and 4 and 8.
676    //   These options use the shaders ability to a free *|/ by 2|4|8.
677    // For all other platforms can be a non-power of two.
678    //   8.0 is sharper (default!!!)
679    //   4.0 is softer
680    //   2.0 is really soft (good only for vector graphics inputs)
681    FxaaFloat fxaaConsoleEdgeSharpness,
682    //
683    // Only used on FXAA Console.
684    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.
685    // It is here now to allow easier tuning.
686    // This does not effect PS3, as this needs to be compiled in.
687    //   Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3.
688    //   Due to the PS3 being ALU bound,
689    //   there are only two safe values here: 1/4 and 1/8.
690    //   These options use the shaders ability to a free *|/ by 2|4|8.
691    // The console setting has a different mapping than the quality setting.
692    // Other platforms can use other values.
693    //   0.125 leaves less aliasing, but is softer (default!!!)
694    //   0.25 leaves more aliasing, and is sharper
695    FxaaFloat fxaaConsoleEdgeThreshold,
696    //
697    // Only used on FXAA Console.
698    // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.
699    // It is here now to allow easier tuning.
700    // Trims the algorithm from processing darks.
701    // The console setting has a different mapping than the quality setting.
702    // This only applies when FXAA_EARLY_EXIT is 1.
703    // This does not apply to PS3,
704    // PS3 was simplified to avoid more shader instructions.
705    //   0.06 - faster but more aliasing in darks
706    //   0.05 - default
707    //   0.04 - slower and less aliasing in darks
708    // Special notes when using FXAA_GREEN_AS_LUMA,
709    //   Likely want to set this to zero.
710    //   As colors that are mostly not-green
711    //   will appear very dark in the green channel!
712    //   Tune by looking at mostly non-green content,
713    //   then start at zero and increase until aliasing is a problem.
714    FxaaFloat fxaaConsoleEdgeThresholdMin,
715    //
716    // Extra constants for 360 FXAA Console only.
717    // Use zeros or anything else for other platforms.
718    // These must be in physical constant registers and NOT immedates.
719    // Immedates will result in compiler un-optimizing.
720    // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
721    FxaaFloat4 fxaaConsole360ConstDir
722) {
723/*--------------------------------------------------------------------------*/
724    FxaaFloat2 posM;
725    posM.x = pos.x;
726    posM.y = pos.y;
727    #if (FXAA_GATHER4_ALPHA == 1)
728        #if (FXAA_DISCARD == 0)
729            FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
730            #if (FXAA_GREEN_AS_LUMA == 0)
731                #define lumaM rgbyM.w
732            #else
733                #define lumaM rgbyM.y
734            #endif
735        #endif
736        #if (FXAA_GREEN_AS_LUMA == 0)
737            FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
738            FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
739        #else
740            FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
741            FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
742        #endif
743        #if (FXAA_DISCARD == 1)
744            #define lumaM luma4A.w
745        #endif
746        #define lumaE luma4A.z
747        #define lumaS luma4A.x
748        #define lumaSE luma4A.y
749        #define lumaNW luma4B.w
750        #define lumaN luma4B.z
751        #define lumaW luma4B.x
752    #else
753        FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
754        #if (FXAA_GREEN_AS_LUMA == 0)
755            #define lumaM rgbyM.w
756        #else
757            #define lumaM rgbyM.y
758        #endif
759        FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
760        FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
761        FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
762        FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
763    #endif
764/*--------------------------------------------------------------------------*/
765    FxaaFloat maxSM = max(lumaS, lumaM);
766    FxaaFloat minSM = min(lumaS, lumaM);
767    FxaaFloat maxESM = max(lumaE, maxSM);
768    FxaaFloat minESM = min(lumaE, minSM);
769    FxaaFloat maxWN = max(lumaN, lumaW);
770    FxaaFloat minWN = min(lumaN, lumaW);
771    FxaaFloat rangeMax = max(maxWN, maxESM);
772    FxaaFloat rangeMin = min(minWN, minESM);
773    FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
774    FxaaFloat range = rangeMax - rangeMin;
775    FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
776    FxaaBool earlyExit = range < rangeMaxClamped;
777/*--------------------------------------------------------------------------*/
778    if(earlyExit)
779        #if (FXAA_DISCARD == 1)
780            FxaaDiscard;
781        #else
782            return rgbyM;
783        #endif
784/*--------------------------------------------------------------------------*/
785    #if (FXAA_GATHER4_ALPHA == 0)
786        FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
787        FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
788        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
789        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
790    #else
791        FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
792        FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
793    #endif
794/*--------------------------------------------------------------------------*/
795    FxaaFloat lumaNS = lumaN + lumaS;
796    FxaaFloat lumaWE = lumaW + lumaE;
797    FxaaFloat subpixRcpRange = 1.0/range;
798    FxaaFloat subpixNSWE = lumaNS + lumaWE;
799    FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
800    FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
801/*--------------------------------------------------------------------------*/
802    FxaaFloat lumaNESE = lumaNE + lumaSE;
803    FxaaFloat lumaNWNE = lumaNW + lumaNE;
804    FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
805    FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
806/*--------------------------------------------------------------------------*/
807    FxaaFloat lumaNWSW = lumaNW + lumaSW;
808    FxaaFloat lumaSWSE = lumaSW + lumaSE;
809    FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
810    FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
811    FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
812    FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
813    FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
814    FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
815/*--------------------------------------------------------------------------*/
816    FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
817    FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
818    FxaaBool horzSpan = edgeHorz >= edgeVert;
819    FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
820/*--------------------------------------------------------------------------*/
821    if(!horzSpan) lumaN = lumaW;
822    if(!horzSpan) lumaS = lumaE;
823    if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
824    FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
825/*--------------------------------------------------------------------------*/
826    FxaaFloat gradientN = lumaN - lumaM;
827    FxaaFloat gradientS = lumaS - lumaM;
828    FxaaFloat lumaNN = lumaN + lumaM;
829    FxaaFloat lumaSS = lumaS + lumaM;
830    FxaaBool pairN = abs(gradientN) >= abs(gradientS);
831    FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
832    if(pairN) lengthSign = -lengthSign;
833    FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
834/*--------------------------------------------------------------------------*/
835    FxaaFloat2 posB;
836    posB.x = posM.x;
837    posB.y = posM.y;
838    FxaaFloat2 offNP;
839    offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
840    offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
841    if(!horzSpan) posB.x += lengthSign * 0.5;
842    if( horzSpan) posB.y += lengthSign * 0.5;
843/*--------------------------------------------------------------------------*/
844    FxaaFloat2 posN;
845    posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
846    posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
847    FxaaFloat2 posP;
848    posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
849    posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
850    FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
851    FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
852    FxaaFloat subpixE = subpixC * subpixC;
853    FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
854/*--------------------------------------------------------------------------*/
855    if(!pairN) lumaNN = lumaSS;
856    FxaaFloat gradientScaled = gradient * 1.0/4.0;
857    FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
858    FxaaFloat subpixF = subpixD * subpixE;
859    FxaaBool lumaMLTZero = lumaMM < 0.0;
860/*--------------------------------------------------------------------------*/
861    lumaEndN -= lumaNN * 0.5;
862    lumaEndP -= lumaNN * 0.5;
863    FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
864    FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
865    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
866    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
867    FxaaBool doneNP = (!doneN) || (!doneP);
868    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
869    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
870/*--------------------------------------------------------------------------*/
871    if(doneNP) {
872        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
873        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
874        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
875        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
876        doneN = abs(lumaEndN) >= gradientScaled;
877        doneP = abs(lumaEndP) >= gradientScaled;
878        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
879        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
880        doneNP = (!doneN) || (!doneP);
881        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
882        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
883/*--------------------------------------------------------------------------*/
884        #if (FXAA_QUALITY__PS > 3)
885        if(doneNP) {
886            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
887            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
888            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
889            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
890            doneN = abs(lumaEndN) >= gradientScaled;
891            doneP = abs(lumaEndP) >= gradientScaled;
892            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
893            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
894            doneNP = (!doneN) || (!doneP);
895            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
896            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
897/*--------------------------------------------------------------------------*/
898            #if (FXAA_QUALITY__PS > 4)
899            if(doneNP) {
900                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
901                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
902                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
903                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
904                doneN = abs(lumaEndN) >= gradientScaled;
905                doneP = abs(lumaEndP) >= gradientScaled;
906                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
907                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
908                doneNP = (!doneN) || (!doneP);
909                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
910                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
911/*--------------------------------------------------------------------------*/
912                #if (FXAA_QUALITY__PS > 5)
913                if(doneNP) {
914                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
915                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
916                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
917                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
918                    doneN = abs(lumaEndN) >= gradientScaled;
919                    doneP = abs(lumaEndP) >= gradientScaled;
920                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
921                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
922                    doneNP = (!doneN) || (!doneP);
923                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
924                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
925/*--------------------------------------------------------------------------*/
926                    #if (FXAA_QUALITY__PS > 6)
927                    if(doneNP) {
928                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
929                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
930                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
931                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
932                        doneN = abs(lumaEndN) >= gradientScaled;
933                        doneP = abs(lumaEndP) >= gradientScaled;
934                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
935                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
936                        doneNP = (!doneN) || (!doneP);
937                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
938                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
939/*--------------------------------------------------------------------------*/
940                        #if (FXAA_QUALITY__PS > 7)
941                        if(doneNP) {
942                            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
943                            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
944                            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
945                            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
946                            doneN = abs(lumaEndN) >= gradientScaled;
947                            doneP = abs(lumaEndP) >= gradientScaled;
948                            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
949                            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
950                            doneNP = (!doneN) || (!doneP);
951                            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
952                            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
953/*--------------------------------------------------------------------------*/
954    #if (FXAA_QUALITY__PS > 8)
955    if(doneNP) {
956        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
957        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
958        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
959        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
960        doneN = abs(lumaEndN) >= gradientScaled;
961        doneP = abs(lumaEndP) >= gradientScaled;
962        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
963        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
964        doneNP = (!doneN) || (!doneP);
965        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
966        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
967/*--------------------------------------------------------------------------*/
968        #if (FXAA_QUALITY__PS > 9)
969        if(doneNP) {
970            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
971            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
972            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
973            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
974            doneN = abs(lumaEndN) >= gradientScaled;
975            doneP = abs(lumaEndP) >= gradientScaled;
976            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
977            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
978            doneNP = (!doneN) || (!doneP);
979            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
980            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
981/*--------------------------------------------------------------------------*/
982            #if (FXAA_QUALITY__PS > 10)
983            if(doneNP) {
984                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
985                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
986                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
987                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
988                doneN = abs(lumaEndN) >= gradientScaled;
989                doneP = abs(lumaEndP) >= gradientScaled;
990                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
991                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
992                doneNP = (!doneN) || (!doneP);
993                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
994                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
995/*--------------------------------------------------------------------------*/
996                #if (FXAA_QUALITY__PS > 11)
997                if(doneNP) {
998                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
999                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1000                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1001                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1002                    doneN = abs(lumaEndN) >= gradientScaled;
1003                    doneP = abs(lumaEndP) >= gradientScaled;
1004                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
1005                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
1006                    doneNP = (!doneN) || (!doneP);
1007                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
1008                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
1009/*--------------------------------------------------------------------------*/
1010                    #if (FXAA_QUALITY__PS > 12)
1011                    if(doneNP) {
1012                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1013                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1014                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1015                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1016                        doneN = abs(lumaEndN) >= gradientScaled;
1017                        doneP = abs(lumaEndP) >= gradientScaled;
1018                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
1019                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
1020                        doneNP = (!doneN) || (!doneP);
1021                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
1022                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
1023/*--------------------------------------------------------------------------*/
1024                    }
1025                    #endif
1026/*--------------------------------------------------------------------------*/
1027                }
1028                #endif
1029/*--------------------------------------------------------------------------*/
1030            }
1031            #endif
1032/*--------------------------------------------------------------------------*/
1033        }
1034        #endif
1035/*--------------------------------------------------------------------------*/
1036    }
1037    #endif
1038/*--------------------------------------------------------------------------*/
1039                        }
1040                        #endif
1041/*--------------------------------------------------------------------------*/
1042                    }
1043                    #endif
1044/*--------------------------------------------------------------------------*/
1045                }
1046                #endif
1047/*--------------------------------------------------------------------------*/
1048            }
1049            #endif
1050/*--------------------------------------------------------------------------*/
1051        }
1052        #endif
1053/*--------------------------------------------------------------------------*/
1054    }
1055/*--------------------------------------------------------------------------*/
1056    FxaaFloat dstN = posM.x - posN.x;
1057    FxaaFloat dstP = posP.x - posM.x;
1058    if(!horzSpan) dstN = posM.y - posN.y;
1059    if(!horzSpan) dstP = posP.y - posM.y;
1060/*--------------------------------------------------------------------------*/
1061    FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
1062    FxaaFloat spanLength = (dstP + dstN);
1063    FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
1064    FxaaFloat spanLengthRcp = 1.0/spanLength;
1065/*--------------------------------------------------------------------------*/
1066    FxaaBool directionN = dstN < dstP;
1067    FxaaFloat dst = min(dstN, dstP);
1068    FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
1069    FxaaFloat subpixG = subpixF * subpixF;
1070    FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
1071    FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
1072/*--------------------------------------------------------------------------*/
1073    FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
1074    FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
1075    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
1076    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
1077    #if (FXAA_DISCARD == 1)
1078        return FxaaTexTop(tex, posM);
1079    #else
1080        return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
1081    #endif
1082}
1083/*==========================================================================*/
1084#endif
1085
1086
1087
1088
1089/*============================================================================
1090
1091                         FXAA3 CONSOLE - PC VERSION
1092
1093------------------------------------------------------------------------------
1094Instead of using this on PC, I'd suggest just using FXAA Quality with
1095    #define FXAA_QUALITY__PRESET 10
1096Or
1097    #define FXAA_QUALITY__PRESET 20
1098Either are higher qualilty and almost as fast as this on modern PC GPUs.
1099============================================================================*/
1100#if (FXAA_PC_CONSOLE == 1)
1101/*--------------------------------------------------------------------------*/
1102FxaaFloat4 FxaaPixelShader(
1103    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1104    FxaaFloat2 pos,
1105    FxaaFloat4 fxaaConsolePosPos,
1106    FxaaTex tex,
1107    FxaaTex fxaaConsole360TexExpBiasNegOne,
1108    FxaaTex fxaaConsole360TexExpBiasNegTwo,
1109    FxaaFloat2 fxaaQualityRcpFrame,
1110    FxaaFloat4 fxaaConsoleRcpFrameOpt,
1111    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1112    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1113    FxaaFloat fxaaQualitySubpix,
1114    FxaaFloat fxaaQualityEdgeThreshold,
1115    FxaaFloat fxaaQualityEdgeThresholdMin,
1116    FxaaFloat fxaaConsoleEdgeSharpness,
1117    FxaaFloat fxaaConsoleEdgeThreshold,
1118    FxaaFloat fxaaConsoleEdgeThresholdMin,
1119    FxaaFloat4 fxaaConsole360ConstDir
1120) {
1121/*--------------------------------------------------------------------------*/
1122    FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
1123    FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
1124    FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
1125    FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
1126/*--------------------------------------------------------------------------*/
1127    FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
1128    #if (FXAA_GREEN_AS_LUMA == 0)
1129        FxaaFloat lumaM = rgbyM.w;
1130    #else
1131        FxaaFloat lumaM = rgbyM.y;
1132    #endif
1133/*--------------------------------------------------------------------------*/
1134    FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
1135    lumaNe += 1.0/384.0;
1136    FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
1137/*--------------------------------------------------------------------------*/
1138    FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
1139    FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
1140/*--------------------------------------------------------------------------*/
1141    FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
1142    FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
1143/*--------------------------------------------------------------------------*/
1144    FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
1145/*--------------------------------------------------------------------------*/
1146    FxaaFloat lumaMinM = min(lumaMin, lumaM);
1147    FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
1148    FxaaFloat lumaMaxM = max(lumaMax, lumaM);
1149    FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
1150    FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
1151    FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
1152    if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
1153/*--------------------------------------------------------------------------*/
1154    FxaaFloat2 dir;
1155    dir.x = dirSwMinusNe + dirSeMinusNw;
1156    dir.y = dirSwMinusNe - dirSeMinusNw;
1157/*--------------------------------------------------------------------------*/
1158    FxaaFloat2 dir1 = normalize(dir.xy);
1159    FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
1160    FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
1161/*--------------------------------------------------------------------------*/
1162    FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
1163    FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
1164/*--------------------------------------------------------------------------*/
1165    FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
1166    FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
1167/*--------------------------------------------------------------------------*/
1168    FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
1169    FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
1170/*--------------------------------------------------------------------------*/
1171    #if (FXAA_GREEN_AS_LUMA == 0)
1172        FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
1173    #else
1174        FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
1175    #endif
1176    if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
1177    return rgbyB; }
1178/*==========================================================================*/
1179#endif
1180
1181
1182
1183/*============================================================================
1184
1185                      FXAA3 CONSOLE - 360 PIXEL SHADER
1186
1187------------------------------------------------------------------------------
1188This optimized version thanks to suggestions from Andy Luedke.
1189Should be fully tex bound in all cases.
1190As of the FXAA 3.11 release, I have still not tested this code,
1191however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10.
1192And note this is replacing the old unoptimized version.
1193If it does not work, please let me know so I can fix it.
1194============================================================================*/
1195#if (FXAA_360 == 1)
1196/*--------------------------------------------------------------------------*/
1197[reduceTempRegUsage(4)]
1198float4 FxaaPixelShader(
1199    // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1200    FxaaFloat2 pos,
1201    FxaaFloat4 fxaaConsolePosPos,
1202    FxaaTex tex,
1203    FxaaTex fxaaConsole360TexExpBiasNegOne,
1204    FxaaTex fxaaConsole360TexExpBiasNegTwo,
1205    FxaaFloat2 fxaaQualityRcpFrame,
1206    FxaaFloat4 fxaaConsoleRcpFrameOpt,
1207    FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1208    FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1209    FxaaFloat fxaaQualitySubpix,
1210    FxaaFloat fxaaQualityEdgeThreshold,
1211    FxaaFloat fxaaQualityEdgeThresholdMin,
1212    FxaaFloat fxaaConsoleEdgeSharpness,
1213    FxaaFloat fxaaConsoleEdgeThreshold,
1214    FxaaFloat fxaaConsoleEdgeThresholdMin,
1215    FxaaFloat4 fxaaConsole360ConstDir
1216) {
1217/*--------------------------------------------------------------------------*/
1218    float4 lumaNwNeSwSe;
1219    #if (FXAA_GREEN_AS_LUMA == 0)
1220        asm {
1221            tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
1222            tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false
1223            tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false
1224            tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false
1225        };
1226    #else
1227        asm {
1228            tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
1229            tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX =  0.5, OffsetY = -0.5, UseComputedLOD=false
1230            tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY =  0.5, UseComputedLOD=false
1231            tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX =  0.5, OffsetY =  0.5, UseComputedLOD=false
1232        };
1233    #endif
1234/*--------------------------------------------------------------------------*/
1235    lumaNwNeSwSe.y += 1.0/384.0;
1236    float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
1237    float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
1238    float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
1239    float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
1240/*--------------------------------------------------------------------------*/
1241    float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
1242    #if (FXAA_GREEN_AS_LUMA == 0)
1243        float lumaMinM = min(lumaMin, rgbyM.w);
1244        float lumaMaxM = max(lumaMax, rgbyM.w);
1245    #else
1246        float lumaMinM = min(lumaMin, rgbyM.y);
1247        float lumaMaxM = max(lumaMax, rgbyM.y);
1248    #endif
1249    if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
1250/*--------------------------------------------------------------------------*/
1251    float2 dir;
1252    dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
1253    dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
1254    dir = normalize(dir);
1255/*--------------------------------------------------------------------------*/
1256    float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
1257/*--------------------------------------------------------------------------*/
1258    float4 dir2;
1259    float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
1260    dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
1261    dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
1262/*--------------------------------------------------------------------------*/
1263    float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
1264    float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
1265    float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
1266    float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
1267/*--------------------------------------------------------------------------*/
1268    float4 rgbyA = rgbyN1 + rgbyP1;
1269    float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;
1270/*--------------------------------------------------------------------------*/
1271    float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB;
1272    rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA;
1273    return rgbyR; }
1274/*==========================================================================*/
1275#endif
1276
1277// NOTE(Sergio): Removed rest of shader because compiler complains about long string.
1278