R2 Shaders
Fxaa3_11.h
1 /*============================================================================
2 
3 
4  NVIDIA FXAA 3.11 by TIMOTHY LOTTES
5 
6 
7 ------------------------------------------------------------------------------
8 COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.
9 ------------------------------------------------------------------------------
10 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
11 *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
12 OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
13 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA
14 OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR
15 CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
16 LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
17 OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
18 THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
19 DAMAGES.
20 
21 ------------------------------------------------------------------------------
22  INTEGRATION CHECKLIST
23 ------------------------------------------------------------------------------
24 (1.)
25 In the shader source, setup defines for the desired configuration.
26 When providing multiple shaders (for different presets),
27 simply setup the defines differently in multiple files.
28 Example,
29 
30  #define FXAA_PC 1
31  #define FXAA_HLSL_5 1
32  #define FXAA_QUALITY__PRESET 12
33 
34 Or,
35 
36  #define FXAA_360 1
37 
38 Or,
39 
40  #define FXAA_PS3 1
41 
42 Etc.
43 
44 (2.)
45 Then include this file,
46 
47  #include "Fxaa3_11.h"
48 
49 (3.)
50 Then call the FXAA pixel shader from within your desired shader.
51 Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
52 As for FXAA 3.11 all inputs for all shaders are the same
53 to enable easy porting between platforms.
54 
55  return FxaaPixelShader(...);
56 
57 (4.)
58 Insure pass prior to FXAA outputs RGBL (see next section).
59 Or use,
60 
61  #define FXAA_GREEN_AS_LUMA 1
62 
63 (5.)
64 Setup engine to provide the following constants
65 which are used in the FxaaPixelShader() inputs,
66 
67  FxaaFloat2 fxaaQualityRcpFrame,
68  FxaaFloat4 fxaaConsoleRcpFrameOpt,
69  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
70  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
71  FxaaFloat fxaaQualitySubpix,
72  FxaaFloat fxaaQualityEdgeThreshold,
73  FxaaFloat fxaaQualityEdgeThresholdMin,
74  FxaaFloat fxaaConsoleEdgeSharpness,
75  FxaaFloat fxaaConsoleEdgeThreshold,
76  FxaaFloat fxaaConsoleEdgeThresholdMin,
77  FxaaFloat4 fxaaConsole360ConstDir
78 
79 Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
80 
81 (6.)
82 Have FXAA vertex shader run as a full screen triangle,
83 and output "pos" and "fxaaConsolePosPos"
84 such that inputs in the pixel shader provide,
85 
86  // {xy} = center of pixel
87  FxaaFloat2 pos,
88 
89  // {xy__} = upper left of pixel
90  // {__zw} = lower right of pixel
91  FxaaFloat4 fxaaConsolePosPos,
92 
93 (7.)
94 Insure the texture sampler(s) used by FXAA are set to bilinear filtering.
95 
96 
97 ------------------------------------------------------------------------------
98  INTEGRATION - RGBL AND COLORSPACE
99 ------------------------------------------------------------------------------
100 FXAA3 requires RGBL as input unless the following is set,
101 
102  #define FXAA_GREEN_AS_LUMA 1
103 
104 In which case the engine uses green in place of luma,
105 and requires RGB input is in a non-linear colorspace.
106 
107 RGB should be LDR (low dynamic range).
108 Specifically do FXAA after tonemapping.
109 
110 RGB data as returned by a texture fetch can be non-linear,
111 or linear when FXAA_GREEN_AS_LUMA is not set.
112 Note an "sRGB format" texture counts as linear,
113 because the result of a texture fetch is linear data.
114 Regular "RGBA8" textures in the sRGB colorspace are non-linear.
115 
116 If FXAA_GREEN_AS_LUMA is not set,
117 luma must be stored in the alpha channel prior to running FXAA.
118 This luma should be in a perceptual space (could be gamma 2.0).
119 Example pass before FXAA where output is gamma 2.0 encoded,
120 
121  color.rgb = ToneMap(color.rgb); // linear color output
122  color.rgb = sqrt(color.rgb); // gamma 2.0 color output
123  return color;
124 
125 To use FXAA,
126 
127  color.rgb = ToneMap(color.rgb); // linear color output
128  color.rgb = sqrt(color.rgb); // gamma 2.0 color output
129  color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma
130  return color;
131 
132 Another example where output is linear encoded,
133 say for instance writing to an sRGB formated render target,
134 where the render target does the conversion back to sRGB after blending,
135 
136  color.rgb = ToneMap(color.rgb); // linear color output
137  return color;
138 
139 To use FXAA,
140 
141  color.rgb = ToneMap(color.rgb); // linear color output
142  color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma
143  return color;
144 
145 Getting luma correct is required for the algorithm to work correctly.
146 
147 
148 ------------------------------------------------------------------------------
149  BEING LINEARLY CORRECT?
150 ------------------------------------------------------------------------------
151 Applying FXAA to a framebuffer with linear RGB color will look worse.
152 This is very counter intuitive, but happends to be true in this case.
153 The reason is because dithering artifacts will be more visiable
154 in a linear colorspace.
155 
156 
157 ------------------------------------------------------------------------------
158  COMPLEX INTEGRATION
159 ------------------------------------------------------------------------------
160 Q. What if the engine is blending into RGB before wanting to run FXAA?
161 
162 A. In the last opaque pass prior to FXAA,
163  have the pass write out luma into alpha.
164  Then blend into RGB only.
165  FXAA should be able to run ok
166  assuming the blending pass did not any add aliasing.
167  This should be the common case for particles and common blending passes.
168 
169 A. Or use FXAA_GREEN_AS_LUMA.
170 
171 ============================================================================*/
172 
173 /*============================================================================
174 
175  INTEGRATION KNOBS
176 
177 ============================================================================*/
178 //
179 // FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).
180 // FXAA_360_OPT is a prototype for the new optimized 360 version.
181 //
182 // 1 = Use API.
183 // 0 = Don't use API.
184 //
185 /*--------------------------------------------------------------------------*/
186 #ifndef FXAA_PS3
187  #define FXAA_PS3 0
188 #endif
189 /*--------------------------------------------------------------------------*/
190 #ifndef FXAA_360
191  #define FXAA_360 0
192 #endif
193 /*--------------------------------------------------------------------------*/
194 #ifndef FXAA_360_OPT
195  #define FXAA_360_OPT 0
196 #endif
197 /*==========================================================================*/
198 #ifndef FXAA_PC
199  //
200  // FXAA Quality
201  // The high quality PC algorithm.
202  //
203  #define FXAA_PC 0
204 #endif
205 /*--------------------------------------------------------------------------*/
206 #ifndef FXAA_PC_CONSOLE
207  //
208  // The console algorithm for PC is included
209  // for developers targeting really low spec machines.
210  // Likely better to just run FXAA_PC, and use a really low preset.
211  //
212  #define FXAA_PC_CONSOLE 0
213 #endif
214 /*--------------------------------------------------------------------------*/
215 #ifndef FXAA_GLSL_120
216  #define FXAA_GLSL_120 0
217 #endif
218 /*--------------------------------------------------------------------------*/
219 #ifndef FXAA_GLSL_130
220  #define FXAA_GLSL_130 0
221 #endif
222 /*--------------------------------------------------------------------------*/
223 #ifndef FXAA_HLSL_3
224  #define FXAA_HLSL_3 0
225 #endif
226 /*--------------------------------------------------------------------------*/
227 #ifndef FXAA_HLSL_4
228  #define FXAA_HLSL_4 0
229 #endif
230 /*--------------------------------------------------------------------------*/
231 #ifndef FXAA_HLSL_5
232  #define FXAA_HLSL_5 0
233 #endif
234 /*==========================================================================*/
235 #ifndef FXAA_GREEN_AS_LUMA
236  //
237  // For those using non-linear color,
238  // and either not able to get luma in alpha, or not wanting to,
239  // this enables FXAA to run using green as a proxy for luma.
240  // So with this enabled, no need to pack luma in alpha.
241  //
242  // This will turn off AA on anything which lacks some amount of green.
243  // Pure red and blue or combination of only R and B, will get no AA.
244  //
245  // Might want to lower the settings for both,
246  // fxaaConsoleEdgeThresholdMin
247  // fxaaQualityEdgeThresholdMin
248  // In order to insure AA does not get turned off on colors
249  // which contain a minor amount of green.
250  //
251  // 1 = On.
252  // 0 = Off.
253  //
254  #define FXAA_GREEN_AS_LUMA 0
255 #endif
256 /*--------------------------------------------------------------------------*/
257 #ifndef FXAA_EARLY_EXIT
258  //
259  // Controls algorithm's early exit path.
260  // On PS3 turning this ON adds 2 cycles to the shader.
261  // On 360 turning this OFF adds 10ths of a millisecond to the shader.
262  // Turning this off on console will result in a more blurry image.
263  // So this defaults to on.
264  //
265  // 1 = On.
266  // 0 = Off.
267  //
268  #define FXAA_EARLY_EXIT 1
269 #endif
270 /*--------------------------------------------------------------------------*/
271 #ifndef FXAA_DISCARD
272  //
273  // Only valid for PC OpenGL currently.
274  // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
275  //
276  // 1 = Use discard on pixels which don't need AA.
277  // For APIs which enable concurrent TEX+ROP from same surface.
278  // 0 = Return unchanged color on pixels which don't need AA.
279  //
280  #define FXAA_DISCARD 0
281 #endif
282 /*--------------------------------------------------------------------------*/
283 #ifndef FXAA_FAST_PIXEL_OFFSET
284  //
285  // Used for GLSL 120 only.
286  //
287  // 1 = GL API supports fast pixel offsets
288  // 0 = do not use fast pixel offsets
289  //
290  #ifdef GL_EXT_gpu_shader4
291  #define FXAA_FAST_PIXEL_OFFSET 1
292  #endif
293  #ifdef GL_NV_gpu_shader5
294  #define FXAA_FAST_PIXEL_OFFSET 1
295  #endif
296  #ifdef GL_ARB_gpu_shader5
297  #define FXAA_FAST_PIXEL_OFFSET 1
298  #endif
299  #ifndef FXAA_FAST_PIXEL_OFFSET
300  #define FXAA_FAST_PIXEL_OFFSET 0
301  #endif
302 #endif
303 /*--------------------------------------------------------------------------*/
304 #ifndef FXAA_GATHER4_ALPHA
305  //
306  // 1 = API supports gather4 on alpha channel.
307  // 0 = API does not support gather4 on alpha channel.
308  //
309  #if (FXAA_HLSL_5 == 1)
310  #define FXAA_GATHER4_ALPHA 1
311  #endif
312  #ifdef GL_ARB_gpu_shader5
313  #define FXAA_GATHER4_ALPHA 1
314  #endif
315  #ifdef GL_NV_gpu_shader5
316  #define FXAA_GATHER4_ALPHA 1
317  #endif
318  #ifndef FXAA_GATHER4_ALPHA
319  #define FXAA_GATHER4_ALPHA 0
320  #endif
321 #endif
322 
323 /*============================================================================
324  FXAA CONSOLE PS3 - TUNING KNOBS
325 ============================================================================*/
326 #ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS
327  //
328  // Consoles the sharpness of edges on PS3 only.
329  // Non-PS3 tuning is done with shader input.
330  //
331  // Due to the PS3 being ALU bound,
332  // there are only two safe values here: 4 and 8.
333  // These options use the shaders ability to a free *|/ by 2|4|8.
334  //
335  // 8.0 is sharper
336  // 4.0 is softer
337  // 2.0 is really soft (good for vector graphics inputs)
338  //
339  #if 1
340  #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
341  #endif
342  #if 0
343  #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
344  #endif
345  #if 0
346  #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
347  #endif
348 #endif
349 /*--------------------------------------------------------------------------*/
350 #ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD
351  //
352  // Only effects PS3.
353  // Non-PS3 tuning is done with shader input.
354  //
355  // The minimum amount of local contrast required to apply algorithm.
356  // The console setting has a different mapping than the quality setting.
357  //
358  // This only applies when FXAA_EARLY_EXIT is 1.
359  //
360  // Due to the PS3 being ALU bound,
361  // there are only two safe values here: 0.25 and 0.125.
362  // These options use the shaders ability to a free *|/ by 2|4|8.
363  //
364  // 0.125 leaves less aliasing, but is softer
365  // 0.25 leaves more aliasing, and is sharper
366  //
367  #if 1
368  #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
369  #else
370  #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
371  #endif
372 #endif
373 
374 /*============================================================================
375  FXAA QUALITY - TUNING KNOBS
376 ------------------------------------------------------------------------------
377 NOTE the other tuning knobs are now in the shader function inputs!
378 ============================================================================*/
379 #ifndef FXAA_QUALITY__PRESET
380  //
381  // Choose the quality preset.
382  // This needs to be compiled into the shader as it effects code.
383  // Best option to include multiple presets is to
384  // in each shader define the preset, then include this file.
385  //
386  // OPTIONS
387  // -----------------------------------------------------------------------
388  // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
389  // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
390  // 39 - no dither, very expensive
391  //
392  // NOTES
393  // -----------------------------------------------------------------------
394  // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
395  // 13 = about same speed as FXAA 3.9 and better than 12
396  // 23 = closest to FXAA 3.9 visually and performance wise
397  // _ = the lowest digit is directly related to performance
398  // _ = the highest digit is directly related to style
399  //
400  #define FXAA_QUALITY__PRESET 12
401 #endif
402 
403 
404 /*============================================================================
405 
406  FXAA QUALITY - PRESETS
407 
408 ============================================================================*/
409 
410 /*============================================================================
411  FXAA QUALITY - MEDIUM DITHER PRESETS
412 ============================================================================*/
413 #if (FXAA_QUALITY__PRESET == 10)
414  #define FXAA_QUALITY__PS 3
415  #define FXAA_QUALITY__P0 1.5
416  #define FXAA_QUALITY__P1 3.0
417  #define FXAA_QUALITY__P2 12.0
418 #endif
419 /*--------------------------------------------------------------------------*/
420 #if (FXAA_QUALITY__PRESET == 11)
421  #define FXAA_QUALITY__PS 4
422  #define FXAA_QUALITY__P0 1.0
423  #define FXAA_QUALITY__P1 1.5
424  #define FXAA_QUALITY__P2 3.0
425  #define FXAA_QUALITY__P3 12.0
426 #endif
427 /*--------------------------------------------------------------------------*/
428 #if (FXAA_QUALITY__PRESET == 12)
429  #define FXAA_QUALITY__PS 5
430  #define FXAA_QUALITY__P0 1.0
431  #define FXAA_QUALITY__P1 1.5
432  #define FXAA_QUALITY__P2 2.0
433  #define FXAA_QUALITY__P3 4.0
434  #define FXAA_QUALITY__P4 12.0
435 #endif
436 /*--------------------------------------------------------------------------*/
437 #if (FXAA_QUALITY__PRESET == 13)
438  #define FXAA_QUALITY__PS 6
439  #define FXAA_QUALITY__P0 1.0
440  #define FXAA_QUALITY__P1 1.5
441  #define FXAA_QUALITY__P2 2.0
442  #define FXAA_QUALITY__P3 2.0
443  #define FXAA_QUALITY__P4 4.0
444  #define FXAA_QUALITY__P5 12.0
445 #endif
446 /*--------------------------------------------------------------------------*/
447 #if (FXAA_QUALITY__PRESET == 14)
448  #define FXAA_QUALITY__PS 7
449  #define FXAA_QUALITY__P0 1.0
450  #define FXAA_QUALITY__P1 1.5
451  #define FXAA_QUALITY__P2 2.0
452  #define FXAA_QUALITY__P3 2.0
453  #define FXAA_QUALITY__P4 2.0
454  #define FXAA_QUALITY__P5 4.0
455  #define FXAA_QUALITY__P6 12.0
456 #endif
457 /*--------------------------------------------------------------------------*/
458 #if (FXAA_QUALITY__PRESET == 15)
459  #define FXAA_QUALITY__PS 8
460  #define FXAA_QUALITY__P0 1.0
461  #define FXAA_QUALITY__P1 1.5
462  #define FXAA_QUALITY__P2 2.0
463  #define FXAA_QUALITY__P3 2.0
464  #define FXAA_QUALITY__P4 2.0
465  #define FXAA_QUALITY__P5 2.0
466  #define FXAA_QUALITY__P6 4.0
467  #define FXAA_QUALITY__P7 12.0
468 #endif
469 
470 /*============================================================================
471  FXAA QUALITY - LOW DITHER PRESETS
472 ============================================================================*/
473 #if (FXAA_QUALITY__PRESET == 20)
474  #define FXAA_QUALITY__PS 3
475  #define FXAA_QUALITY__P0 1.5
476  #define FXAA_QUALITY__P1 2.0
477  #define FXAA_QUALITY__P2 8.0
478 #endif
479 /*--------------------------------------------------------------------------*/
480 #if (FXAA_QUALITY__PRESET == 21)
481  #define FXAA_QUALITY__PS 4
482  #define FXAA_QUALITY__P0 1.0
483  #define FXAA_QUALITY__P1 1.5
484  #define FXAA_QUALITY__P2 2.0
485  #define FXAA_QUALITY__P3 8.0
486 #endif
487 /*--------------------------------------------------------------------------*/
488 #if (FXAA_QUALITY__PRESET == 22)
489  #define FXAA_QUALITY__PS 5
490  #define FXAA_QUALITY__P0 1.0
491  #define FXAA_QUALITY__P1 1.5
492  #define FXAA_QUALITY__P2 2.0
493  #define FXAA_QUALITY__P3 2.0
494  #define FXAA_QUALITY__P4 8.0
495 #endif
496 /*--------------------------------------------------------------------------*/
497 #if (FXAA_QUALITY__PRESET == 23)
498  #define FXAA_QUALITY__PS 6
499  #define FXAA_QUALITY__P0 1.0
500  #define FXAA_QUALITY__P1 1.5
501  #define FXAA_QUALITY__P2 2.0
502  #define FXAA_QUALITY__P3 2.0
503  #define FXAA_QUALITY__P4 2.0
504  #define FXAA_QUALITY__P5 8.0
505 #endif
506 /*--------------------------------------------------------------------------*/
507 #if (FXAA_QUALITY__PRESET == 24)
508  #define FXAA_QUALITY__PS 7
509  #define FXAA_QUALITY__P0 1.0
510  #define FXAA_QUALITY__P1 1.5
511  #define FXAA_QUALITY__P2 2.0
512  #define FXAA_QUALITY__P3 2.0
513  #define FXAA_QUALITY__P4 2.0
514  #define FXAA_QUALITY__P5 3.0
515  #define FXAA_QUALITY__P6 8.0
516 #endif
517 /*--------------------------------------------------------------------------*/
518 #if (FXAA_QUALITY__PRESET == 25)
519  #define FXAA_QUALITY__PS 8
520  #define FXAA_QUALITY__P0 1.0
521  #define FXAA_QUALITY__P1 1.5
522  #define FXAA_QUALITY__P2 2.0
523  #define FXAA_QUALITY__P3 2.0
524  #define FXAA_QUALITY__P4 2.0
525  #define FXAA_QUALITY__P5 2.0
526  #define FXAA_QUALITY__P6 4.0
527  #define FXAA_QUALITY__P7 8.0
528 #endif
529 /*--------------------------------------------------------------------------*/
530 #if (FXAA_QUALITY__PRESET == 26)
531  #define FXAA_QUALITY__PS 9
532  #define FXAA_QUALITY__P0 1.0
533  #define FXAA_QUALITY__P1 1.5
534  #define FXAA_QUALITY__P2 2.0
535  #define FXAA_QUALITY__P3 2.0
536  #define FXAA_QUALITY__P4 2.0
537  #define FXAA_QUALITY__P5 2.0
538  #define FXAA_QUALITY__P6 2.0
539  #define FXAA_QUALITY__P7 4.0
540  #define FXAA_QUALITY__P8 8.0
541 #endif
542 /*--------------------------------------------------------------------------*/
543 #if (FXAA_QUALITY__PRESET == 27)
544  #define FXAA_QUALITY__PS 10
545  #define FXAA_QUALITY__P0 1.0
546  #define FXAA_QUALITY__P1 1.5
547  #define FXAA_QUALITY__P2 2.0
548  #define FXAA_QUALITY__P3 2.0
549  #define FXAA_QUALITY__P4 2.0
550  #define FXAA_QUALITY__P5 2.0
551  #define FXAA_QUALITY__P6 2.0
552  #define FXAA_QUALITY__P7 2.0
553  #define FXAA_QUALITY__P8 4.0
554  #define FXAA_QUALITY__P9 8.0
555 #endif
556 /*--------------------------------------------------------------------------*/
557 #if (FXAA_QUALITY__PRESET == 28)
558  #define FXAA_QUALITY__PS 11
559  #define FXAA_QUALITY__P0 1.0
560  #define FXAA_QUALITY__P1 1.5
561  #define FXAA_QUALITY__P2 2.0
562  #define FXAA_QUALITY__P3 2.0
563  #define FXAA_QUALITY__P4 2.0
564  #define FXAA_QUALITY__P5 2.0
565  #define FXAA_QUALITY__P6 2.0
566  #define FXAA_QUALITY__P7 2.0
567  #define FXAA_QUALITY__P8 2.0
568  #define FXAA_QUALITY__P9 4.0
569  #define FXAA_QUALITY__P10 8.0
570 #endif
571 /*--------------------------------------------------------------------------*/
572 #if (FXAA_QUALITY__PRESET == 29)
573  #define FXAA_QUALITY__PS 12
574  #define FXAA_QUALITY__P0 1.0
575  #define FXAA_QUALITY__P1 1.5
576  #define FXAA_QUALITY__P2 2.0
577  #define FXAA_QUALITY__P3 2.0
578  #define FXAA_QUALITY__P4 2.0
579  #define FXAA_QUALITY__P5 2.0
580  #define FXAA_QUALITY__P6 2.0
581  #define FXAA_QUALITY__P7 2.0
582  #define FXAA_QUALITY__P8 2.0
583  #define FXAA_QUALITY__P9 2.0
584  #define FXAA_QUALITY__P10 4.0
585  #define FXAA_QUALITY__P11 8.0
586 #endif
587 
588 /*============================================================================
589  FXAA QUALITY - EXTREME QUALITY
590 ============================================================================*/
591 #if (FXAA_QUALITY__PRESET == 39)
592  #define FXAA_QUALITY__PS 12
593  #define FXAA_QUALITY__P0 1.0
594  #define FXAA_QUALITY__P1 1.0
595  #define FXAA_QUALITY__P2 1.0
596  #define FXAA_QUALITY__P3 1.0
597  #define FXAA_QUALITY__P4 1.0
598  #define FXAA_QUALITY__P5 1.5
599  #define FXAA_QUALITY__P6 2.0
600  #define FXAA_QUALITY__P7 2.0
601  #define FXAA_QUALITY__P8 2.0
602  #define FXAA_QUALITY__P9 2.0
603  #define FXAA_QUALITY__P10 4.0
604  #define FXAA_QUALITY__P11 8.0
605 #endif
606 
607 
608 
609 /*============================================================================
610 
611  API PORTING
612 
613 ============================================================================*/
614 #if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
615  #define FxaaBool bool
616  #define FxaaDiscard discard
617  #define FxaaFloat float
618  #define FxaaFloat2 vec2
619  #define FxaaFloat3 vec3
620  #define FxaaFloat4 vec4
621  #define FxaaHalf float
622  #define FxaaHalf2 vec2
623  #define FxaaHalf3 vec3
624  #define FxaaHalf4 vec4
625  #define FxaaInt2 ivec2
626  #define FxaaSat(x) clamp(x, 0.0, 1.0)
627  #define FxaaTex sampler2D
628 #else
629  #define FxaaBool bool
630  #define FxaaDiscard clip(-1)
631  #define FxaaFloat float
632  #define FxaaFloat2 float2
633  #define FxaaFloat3 float3
634  #define FxaaFloat4 float4
635  #define FxaaHalf half
636  #define FxaaHalf2 half2
637  #define FxaaHalf3 half3
638  #define FxaaHalf4 half4
639  #define FxaaSat(x) saturate(x)
640 #endif
641 /*--------------------------------------------------------------------------*/
642 #if (FXAA_GLSL_120 == 1)
643  // Requires,
644  // #version 120
645  // And at least,
646  // #extension GL_EXT_gpu_shader4 : enable
647  // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
648  #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
649  #if (FXAA_FAST_PIXEL_OFFSET == 1)
650  #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
651  #else
652  #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
653  #endif
654  #if (FXAA_GATHER4_ALPHA == 1)
655  // use #extension GL_ARB_gpu_shader5 : enable
656  #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
657  #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
658  #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
659  #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
660  #endif
661 #endif
662 /*--------------------------------------------------------------------------*/
663 #if (FXAA_GLSL_130 == 1)
664  // Requires "#version 130" or better
665  #define FxaaTexTop(t, p) textureLod(t, p, 0.0)
666  #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
667  #if (FXAA_GATHER4_ALPHA == 1)
668  // use #extension GL_ARB_gpu_shader5 : enable
669  #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
670  #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
671  #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
672  #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
673  #endif
674 #endif
675 /*--------------------------------------------------------------------------*/
676 #if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
677  #define FxaaInt2 float2
678  #define FxaaTex sampler2D
679  #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
680  #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
681 #endif
682 /*--------------------------------------------------------------------------*/
683 #if (FXAA_HLSL_4 == 1)
684  #define FxaaInt2 int2
685  struct FxaaTex { SamplerState smpl; Texture2D tex; };
686  #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
687  #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
688 #endif
689 /*--------------------------------------------------------------------------*/
690 #if (FXAA_HLSL_5 == 1)
691  #define FxaaInt2 int2
692  struct FxaaTex { SamplerState smpl; Texture2D tex; };
693  #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
694  #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
695  #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
696  #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
697  #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
698  #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
699 #endif
700 
701 
702 /*============================================================================
703  GREEN AS LUMA OPTION SUPPORT FUNCTION
704 ============================================================================*/
705 #if (FXAA_GREEN_AS_LUMA == 0)
706  FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
707 #else
708  FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
709 #endif
710 
711 
712 
713 
714 /*============================================================================
715 
716  FXAA3 QUALITY - PC
717 
718 ============================================================================*/
719 #if (FXAA_PC == 1)
720 /*--------------------------------------------------------------------------*/
721 FxaaFloat4 FxaaPixelShader(
722  //
723  // Use noperspective interpolation here (turn off perspective interpolation).
724  // {xy} = center of pixel
725  FxaaFloat2 pos,
726  //
727  // Used only for FXAA Console, and not used on the 360 version.
728  // Use noperspective interpolation here (turn off perspective interpolation).
729  // {xy__} = upper left of pixel
730  // {__zw} = lower right of pixel
731  FxaaFloat4 fxaaConsolePosPos,
732  //
733  // Input color texture.
734  // {rgb_} = color in linear or perceptual color space
735  // if (FXAA_GREEN_AS_LUMA == 0)
736  // {___a} = luma in perceptual color space (not linear)
737  FxaaTex tex,
738  //
739  // Only used on the optimized 360 version of FXAA Console.
740  // For everything but 360, just use the same input here as for "tex".
741  // For 360, same texture, just alias with a 2nd sampler.
742  // This sampler needs to have an exponent bias of -1.
743  FxaaTex fxaaConsole360TexExpBiasNegOne,
744  //
745  // Only used on the optimized 360 version of FXAA Console.
746  // For everything but 360, just use the same input here as for "tex".
747  // For 360, same texture, just alias with a 3nd sampler.
748  // This sampler needs to have an exponent bias of -2.
749  FxaaTex fxaaConsole360TexExpBiasNegTwo,
750  //
751  // Only used on FXAA Quality.
752  // This must be from a constant/uniform.
753  // {x_} = 1.0/screenWidthInPixels
754  // {_y} = 1.0/screenHeightInPixels
755  FxaaFloat2 fxaaQualityRcpFrame,
756  //
757  // Only used on FXAA Console.
758  // This must be from a constant/uniform.
759  // This effects sub-pixel AA quality and inversely sharpness.
760  // Where N ranges between,
761  // N = 0.50 (default)
762  // N = 0.33 (sharper)
763  // {x___} = -N/screenWidthInPixels
764  // {_y__} = -N/screenHeightInPixels
765  // {__z_} = N/screenWidthInPixels
766  // {___w} = N/screenHeightInPixels
767  FxaaFloat4 fxaaConsoleRcpFrameOpt,
768  //
769  // Only used on FXAA Console.
770  // Not used on 360, but used on PS3 and PC.
771  // This must be from a constant/uniform.
772  // {x___} = -2.0/screenWidthInPixels
773  // {_y__} = -2.0/screenHeightInPixels
774  // {__z_} = 2.0/screenWidthInPixels
775  // {___w} = 2.0/screenHeightInPixels
776  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
777  //
778  // Only used on FXAA Console.
779  // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
780  // This must be from a constant/uniform.
781  // {x___} = 8.0/screenWidthInPixels
782  // {_y__} = 8.0/screenHeightInPixels
783  // {__z_} = -4.0/screenWidthInPixels
784  // {___w} = -4.0/screenHeightInPixels
785  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
786  //
787  // Only used on FXAA Quality.
788  // This used to be the FXAA_QUALITY__SUBPIX define.
789  // It is here now to allow easier tuning.
790  // Choose the amount of sub-pixel aliasing removal.
791  // This can effect sharpness.
792  // 1.00 - upper limit (softer)
793  // 0.75 - default amount of filtering
794  // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
795  // 0.25 - almost off
796  // 0.00 - completely off
797  FxaaFloat fxaaQualitySubpix,
798  //
799  // Only used on FXAA Quality.
800  // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
801  // It is here now to allow easier tuning.
802  // The minimum amount of local contrast required to apply algorithm.
803  // 0.333 - too little (faster)
804  // 0.250 - low quality
805  // 0.166 - default
806  // 0.125 - high quality
807  // 0.063 - overkill (slower)
808  FxaaFloat fxaaQualityEdgeThreshold,
809  //
810  // Only used on FXAA Quality.
811  // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
812  // It is here now to allow easier tuning.
813  // Trims the algorithm from processing darks.
814  // 0.0833 - upper limit (default, the start of visible unfiltered edges)
815  // 0.0625 - high quality (faster)
816  // 0.0312 - visible limit (slower)
817  // Special notes when using FXAA_GREEN_AS_LUMA,
818  // Likely want to set this to zero.
819  // As colors that are mostly not-green
820  // will appear very dark in the green channel!
821  // Tune by looking at mostly non-green content,
822  // then start at zero and increase until aliasing is a problem.
823  FxaaFloat fxaaQualityEdgeThresholdMin,
824  //
825  // Only used on FXAA Console.
826  // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
827  // It is here now to allow easier tuning.
828  // This does not effect PS3, as this needs to be compiled in.
829  // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
830  // Due to the PS3 being ALU bound,
831  // there are only three safe values here: 2 and 4 and 8.
832  // These options use the shaders ability to a free *|/ by 2|4|8.
833  // For all other platforms can be a non-power of two.
834  // 8.0 is sharper (default!!!)
835  // 4.0 is softer
836  // 2.0 is really soft (good only for vector graphics inputs)
837  FxaaFloat fxaaConsoleEdgeSharpness,
838  //
839  // Only used on FXAA Console.
840  // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.
841  // It is here now to allow easier tuning.
842  // This does not effect PS3, as this needs to be compiled in.
843  // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3.
844  // Due to the PS3 being ALU bound,
845  // there are only two safe values here: 1/4 and 1/8.
846  // These options use the shaders ability to a free *|/ by 2|4|8.
847  // The console setting has a different mapping than the quality setting.
848  // Other platforms can use other values.
849  // 0.125 leaves less aliasing, but is softer (default!!!)
850  // 0.25 leaves more aliasing, and is sharper
851  FxaaFloat fxaaConsoleEdgeThreshold,
852  //
853  // Only used on FXAA Console.
854  // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.
855  // It is here now to allow easier tuning.
856  // Trims the algorithm from processing darks.
857  // The console setting has a different mapping than the quality setting.
858  // This only applies when FXAA_EARLY_EXIT is 1.
859  // This does not apply to PS3,
860  // PS3 was simplified to avoid more shader instructions.
861  // 0.06 - faster but more aliasing in darks
862  // 0.05 - default
863  // 0.04 - slower and less aliasing in darks
864  // Special notes when using FXAA_GREEN_AS_LUMA,
865  // Likely want to set this to zero.
866  // As colors that are mostly not-green
867  // will appear very dark in the green channel!
868  // Tune by looking at mostly non-green content,
869  // then start at zero and increase until aliasing is a problem.
870  FxaaFloat fxaaConsoleEdgeThresholdMin,
871  //
872  // Extra constants for 360 FXAA Console only.
873  // Use zeros or anything else for other platforms.
874  // These must be in physical constant registers and NOT immedates.
875  // Immedates will result in compiler un-optimizing.
876  // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
877  FxaaFloat4 fxaaConsole360ConstDir
878 ) {
879 /*--------------------------------------------------------------------------*/
880  FxaaFloat2 posM;
881  posM.x = pos.x;
882  posM.y = pos.y;
883  #if (FXAA_GATHER4_ALPHA == 1)
884  #if (FXAA_DISCARD == 0)
885  FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
886  #if (FXAA_GREEN_AS_LUMA == 0)
887  #define lumaM rgbyM.w
888  #else
889  #define lumaM rgbyM.y
890  #endif
891  #endif
892  #if (FXAA_GREEN_AS_LUMA == 0)
893  FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
894  FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
895  #else
896  FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
897  FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
898  #endif
899  #if (FXAA_DISCARD == 1)
900  #define lumaM luma4A.w
901  #endif
902  #define lumaE luma4A.z
903  #define lumaS luma4A.x
904  #define lumaSE luma4A.y
905  #define lumaNW luma4B.w
906  #define lumaN luma4B.z
907  #define lumaW luma4B.x
908  #else
909  FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
910  #if (FXAA_GREEN_AS_LUMA == 0)
911  #define lumaM rgbyM.w
912  #else
913  #define lumaM rgbyM.y
914  #endif
915  FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
916  FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
917  FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
918  FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
919  #endif
920 /*--------------------------------------------------------------------------*/
921  FxaaFloat maxSM = max(lumaS, lumaM);
922  FxaaFloat minSM = min(lumaS, lumaM);
923  FxaaFloat maxESM = max(lumaE, maxSM);
924  FxaaFloat minESM = min(lumaE, minSM);
925  FxaaFloat maxWN = max(lumaN, lumaW);
926  FxaaFloat minWN = min(lumaN, lumaW);
927  FxaaFloat rangeMax = max(maxWN, maxESM);
928  FxaaFloat rangeMin = min(minWN, minESM);
929  FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
930  FxaaFloat range = rangeMax - rangeMin;
931  FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
932  FxaaBool earlyExit = range < rangeMaxClamped;
933 /*--------------------------------------------------------------------------*/
934  if(earlyExit)
935  #if (FXAA_DISCARD == 1)
936  FxaaDiscard;
937  #else
938  return rgbyM;
939  #endif
940 /*--------------------------------------------------------------------------*/
941  #if (FXAA_GATHER4_ALPHA == 0)
942  FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
943  FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
944  FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
945  FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
946  #else
947  FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
948  FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
949  #endif
950 /*--------------------------------------------------------------------------*/
951  FxaaFloat lumaNS = lumaN + lumaS;
952  FxaaFloat lumaWE = lumaW + lumaE;
953  FxaaFloat subpixRcpRange = 1.0/range;
954  FxaaFloat subpixNSWE = lumaNS + lumaWE;
955  FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
956  FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
957 /*--------------------------------------------------------------------------*/
958  FxaaFloat lumaNESE = lumaNE + lumaSE;
959  FxaaFloat lumaNWNE = lumaNW + lumaNE;
960  FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
961  FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
962 /*--------------------------------------------------------------------------*/
963  FxaaFloat lumaNWSW = lumaNW + lumaSW;
964  FxaaFloat lumaSWSE = lumaSW + lumaSE;
965  FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
966  FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
967  FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
968  FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
969  FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
970  FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
971 /*--------------------------------------------------------------------------*/
972  FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
973  FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
974  FxaaBool horzSpan = edgeHorz >= edgeVert;
975  FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
976 /*--------------------------------------------------------------------------*/
977  if(!horzSpan) lumaN = lumaW;
978  if(!horzSpan) lumaS = lumaE;
979  if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
980  FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
981 /*--------------------------------------------------------------------------*/
982  FxaaFloat gradientN = lumaN - lumaM;
983  FxaaFloat gradientS = lumaS - lumaM;
984  FxaaFloat lumaNN = lumaN + lumaM;
985  FxaaFloat lumaSS = lumaS + lumaM;
986  FxaaBool pairN = abs(gradientN) >= abs(gradientS);
987  FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
988  if(pairN) lengthSign = -lengthSign;
989  FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
990 /*--------------------------------------------------------------------------*/
991  FxaaFloat2 posB;
992  posB.x = posM.x;
993  posB.y = posM.y;
994  FxaaFloat2 offNP;
995  offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
996  offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
997  if(!horzSpan) posB.x += lengthSign * 0.5;
998  if( horzSpan) posB.y += lengthSign * 0.5;
999 /*--------------------------------------------------------------------------*/
1000  FxaaFloat2 posN;
1001  posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
1002  posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
1003  FxaaFloat2 posP;
1004  posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
1005  posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
1006  FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
1007  FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
1008  FxaaFloat subpixE = subpixC * subpixC;
1009  FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
1010 /*--------------------------------------------------------------------------*/
1011  if(!pairN) lumaNN = lumaSS;
1012  FxaaFloat gradientScaled = gradient * 1.0/4.0;
1013  FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
1014  FxaaFloat subpixF = subpixD * subpixE;
1015  FxaaBool lumaMLTZero = lumaMM < 0.0;
1016 /*--------------------------------------------------------------------------*/
1017  lumaEndN -= lumaNN * 0.5;
1018  lumaEndP -= lumaNN * 0.5;
1019  FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
1020  FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
1021  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
1022  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
1023  FxaaBool doneNP = (!doneN) || (!doneP);
1024  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
1025  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
1026 /*--------------------------------------------------------------------------*/
1027  if(doneNP) {
1028  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1029  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1030  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1031  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1032  doneN = abs(lumaEndN) >= gradientScaled;
1033  doneP = abs(lumaEndP) >= gradientScaled;
1034  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
1035  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
1036  doneNP = (!doneN) || (!doneP);
1037  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
1038  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
1039 /*--------------------------------------------------------------------------*/
1040  #if (FXAA_QUALITY__PS > 3)
1041  if(doneNP) {
1042  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1043  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1044  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1045  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1046  doneN = abs(lumaEndN) >= gradientScaled;
1047  doneP = abs(lumaEndP) >= gradientScaled;
1048  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
1049  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
1050  doneNP = (!doneN) || (!doneP);
1051  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
1052  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
1053 /*--------------------------------------------------------------------------*/
1054  #if (FXAA_QUALITY__PS > 4)
1055  if(doneNP) {
1056  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1057  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1058  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1059  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1060  doneN = abs(lumaEndN) >= gradientScaled;
1061  doneP = abs(lumaEndP) >= gradientScaled;
1062  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
1063  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
1064  doneNP = (!doneN) || (!doneP);
1065  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
1066  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
1067 /*--------------------------------------------------------------------------*/
1068  #if (FXAA_QUALITY__PS > 5)
1069  if(doneNP) {
1070  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1071  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1072  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1073  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1074  doneN = abs(lumaEndN) >= gradientScaled;
1075  doneP = abs(lumaEndP) >= gradientScaled;
1076  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
1077  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
1078  doneNP = (!doneN) || (!doneP);
1079  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
1080  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
1081 /*--------------------------------------------------------------------------*/
1082  #if (FXAA_QUALITY__PS > 6)
1083  if(doneNP) {
1084  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1085  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1086  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1087  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1088  doneN = abs(lumaEndN) >= gradientScaled;
1089  doneP = abs(lumaEndP) >= gradientScaled;
1090  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
1091  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
1092  doneNP = (!doneN) || (!doneP);
1093  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
1094  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
1095 /*--------------------------------------------------------------------------*/
1096  #if (FXAA_QUALITY__PS > 7)
1097  if(doneNP) {
1098  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1099  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1100  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1101  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1102  doneN = abs(lumaEndN) >= gradientScaled;
1103  doneP = abs(lumaEndP) >= gradientScaled;
1104  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
1105  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
1106  doneNP = (!doneN) || (!doneP);
1107  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
1108  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
1109 /*--------------------------------------------------------------------------*/
1110  #if (FXAA_QUALITY__PS > 8)
1111  if(doneNP) {
1112  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1113  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1114  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1115  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1116  doneN = abs(lumaEndN) >= gradientScaled;
1117  doneP = abs(lumaEndP) >= gradientScaled;
1118  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
1119  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
1120  doneNP = (!doneN) || (!doneP);
1121  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
1122  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
1123 /*--------------------------------------------------------------------------*/
1124  #if (FXAA_QUALITY__PS > 9)
1125  if(doneNP) {
1126  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1127  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1128  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1129  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1130  doneN = abs(lumaEndN) >= gradientScaled;
1131  doneP = abs(lumaEndP) >= gradientScaled;
1132  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
1133  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
1134  doneNP = (!doneN) || (!doneP);
1135  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
1136  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
1137 /*--------------------------------------------------------------------------*/
1138  #if (FXAA_QUALITY__PS > 10)
1139  if(doneNP) {
1140  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1141  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1142  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1143  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1144  doneN = abs(lumaEndN) >= gradientScaled;
1145  doneP = abs(lumaEndP) >= gradientScaled;
1146  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
1147  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
1148  doneNP = (!doneN) || (!doneP);
1149  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
1150  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
1151 /*--------------------------------------------------------------------------*/
1152  #if (FXAA_QUALITY__PS > 11)
1153  if(doneNP) {
1154  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1155  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1156  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1157  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1158  doneN = abs(lumaEndN) >= gradientScaled;
1159  doneP = abs(lumaEndP) >= gradientScaled;
1160  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
1161  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
1162  doneNP = (!doneN) || (!doneP);
1163  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
1164  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
1165 /*--------------------------------------------------------------------------*/
1166  #if (FXAA_QUALITY__PS > 12)
1167  if(doneNP) {
1168  if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
1169  if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
1170  if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
1171  if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
1172  doneN = abs(lumaEndN) >= gradientScaled;
1173  doneP = abs(lumaEndP) >= gradientScaled;
1174  if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
1175  if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
1176  doneNP = (!doneN) || (!doneP);
1177  if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
1178  if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
1179 /*--------------------------------------------------------------------------*/
1180  }
1181  #endif
1182 /*--------------------------------------------------------------------------*/
1183  }
1184  #endif
1185 /*--------------------------------------------------------------------------*/
1186  }
1187  #endif
1188 /*--------------------------------------------------------------------------*/
1189  }
1190  #endif
1191 /*--------------------------------------------------------------------------*/
1192  }
1193  #endif
1194 /*--------------------------------------------------------------------------*/
1195  }
1196  #endif
1197 /*--------------------------------------------------------------------------*/
1198  }
1199  #endif
1200 /*--------------------------------------------------------------------------*/
1201  }
1202  #endif
1203 /*--------------------------------------------------------------------------*/
1204  }
1205  #endif
1206 /*--------------------------------------------------------------------------*/
1207  }
1208  #endif
1209 /*--------------------------------------------------------------------------*/
1210  }
1211 /*--------------------------------------------------------------------------*/
1212  FxaaFloat dstN = posM.x - posN.x;
1213  FxaaFloat dstP = posP.x - posM.x;
1214  if(!horzSpan) dstN = posM.y - posN.y;
1215  if(!horzSpan) dstP = posP.y - posM.y;
1216 /*--------------------------------------------------------------------------*/
1217  FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
1218  FxaaFloat spanLength = (dstP + dstN);
1219  FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
1220  FxaaFloat spanLengthRcp = 1.0/spanLength;
1221 /*--------------------------------------------------------------------------*/
1222  FxaaBool directionN = dstN < dstP;
1223  FxaaFloat dst = min(dstN, dstP);
1224  FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
1225  FxaaFloat subpixG = subpixF * subpixF;
1226  FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
1227  FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
1228 /*--------------------------------------------------------------------------*/
1229  FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
1230  FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
1231  if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
1232  if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
1233  #if (FXAA_DISCARD == 1)
1234  return FxaaTexTop(tex, posM);
1235  #else
1236  return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
1237  #endif
1238 }
1239 /*==========================================================================*/
1240 #endif
1241 
1242 
1243 
1244 
1245 /*============================================================================
1246 
1247  FXAA3 CONSOLE - PC VERSION
1248 
1249 ------------------------------------------------------------------------------
1250 Instead of using this on PC, I'd suggest just using FXAA Quality with
1251  #define FXAA_QUALITY__PRESET 10
1252 Or
1253  #define FXAA_QUALITY__PRESET 20
1254 Either are higher qualilty and almost as fast as this on modern PC GPUs.
1255 ============================================================================*/
1256 #if (FXAA_PC_CONSOLE == 1)
1257 /*--------------------------------------------------------------------------*/
1258 FxaaFloat4 FxaaPixelShader(
1259  // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1260  FxaaFloat2 pos,
1261  FxaaFloat4 fxaaConsolePosPos,
1262  FxaaTex tex,
1263  FxaaTex fxaaConsole360TexExpBiasNegOne,
1264  FxaaTex fxaaConsole360TexExpBiasNegTwo,
1265  FxaaFloat2 fxaaQualityRcpFrame,
1266  FxaaFloat4 fxaaConsoleRcpFrameOpt,
1267  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1268  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1269  FxaaFloat fxaaQualitySubpix,
1270  FxaaFloat fxaaQualityEdgeThreshold,
1271  FxaaFloat fxaaQualityEdgeThresholdMin,
1272  FxaaFloat fxaaConsoleEdgeSharpness,
1273  FxaaFloat fxaaConsoleEdgeThreshold,
1274  FxaaFloat fxaaConsoleEdgeThresholdMin,
1275  FxaaFloat4 fxaaConsole360ConstDir
1276 ) {
1277 /*--------------------------------------------------------------------------*/
1278  FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
1279  FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
1280  FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
1281  FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
1282 /*--------------------------------------------------------------------------*/
1283  FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
1284  #if (FXAA_GREEN_AS_LUMA == 0)
1285  FxaaFloat lumaM = rgbyM.w;
1286  #else
1287  FxaaFloat lumaM = rgbyM.y;
1288  #endif
1289 /*--------------------------------------------------------------------------*/
1290  FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
1291  lumaNe += 1.0/384.0;
1292  FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
1293 /*--------------------------------------------------------------------------*/
1294  FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
1295  FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
1296 /*--------------------------------------------------------------------------*/
1297  FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
1298  FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
1299 /*--------------------------------------------------------------------------*/
1300  FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
1301 /*--------------------------------------------------------------------------*/
1302  FxaaFloat lumaMinM = min(lumaMin, lumaM);
1303  FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
1304  FxaaFloat lumaMaxM = max(lumaMax, lumaM);
1305  FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
1306  FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
1307  FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
1308  if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
1309 /*--------------------------------------------------------------------------*/
1310  FxaaFloat2 dir;
1311  dir.x = dirSwMinusNe + dirSeMinusNw;
1312  dir.y = dirSwMinusNe - dirSeMinusNw;
1313 /*--------------------------------------------------------------------------*/
1314  FxaaFloat2 dir1 = normalize(dir.xy);
1315  FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
1316  FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
1317 /*--------------------------------------------------------------------------*/
1318  FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
1319  FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
1320 /*--------------------------------------------------------------------------*/
1321  FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
1322  FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
1323 /*--------------------------------------------------------------------------*/
1324  FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
1325  FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
1326 /*--------------------------------------------------------------------------*/
1327  #if (FXAA_GREEN_AS_LUMA == 0)
1328  FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
1329  #else
1330  FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
1331  #endif
1332  if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
1333  return rgbyB; }
1334 /*==========================================================================*/
1335 #endif
1336 
1337 
1338 
1339 /*============================================================================
1340 
1341  FXAA3 CONSOLE - 360 PIXEL SHADER
1342 
1343 ------------------------------------------------------------------------------
1344 This optimized version thanks to suggestions from Andy Luedke.
1345 Should be fully tex bound in all cases.
1346 As of the FXAA 3.11 release, I have still not tested this code,
1347 however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10.
1348 And note this is replacing the old unoptimized version.
1349 If it does not work, please let me know so I can fix it.
1350 ============================================================================*/
1351 #if (FXAA_360 == 1)
1352 /*--------------------------------------------------------------------------*/
1353 [reduceTempRegUsage(4)]
1354 float4 FxaaPixelShader(
1355  // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1356  FxaaFloat2 pos,
1357  FxaaFloat4 fxaaConsolePosPos,
1358  FxaaTex tex,
1359  FxaaTex fxaaConsole360TexExpBiasNegOne,
1360  FxaaTex fxaaConsole360TexExpBiasNegTwo,
1361  FxaaFloat2 fxaaQualityRcpFrame,
1362  FxaaFloat4 fxaaConsoleRcpFrameOpt,
1363  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1364  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1365  FxaaFloat fxaaQualitySubpix,
1366  FxaaFloat fxaaQualityEdgeThreshold,
1367  FxaaFloat fxaaQualityEdgeThresholdMin,
1368  FxaaFloat fxaaConsoleEdgeSharpness,
1369  FxaaFloat fxaaConsoleEdgeThreshold,
1370  FxaaFloat fxaaConsoleEdgeThresholdMin,
1371  FxaaFloat4 fxaaConsole360ConstDir
1372 ) {
1373 /*--------------------------------------------------------------------------*/
1374  float4 lumaNwNeSwSe;
1375  #if (FXAA_GREEN_AS_LUMA == 0)
1376  asm {
1377  tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
1378  tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
1379  tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
1380  tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
1381  };
1382  #else
1383  asm {
1384  tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
1385  tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
1386  tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
1387  tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
1388  };
1389  #endif
1390 /*--------------------------------------------------------------------------*/
1391  lumaNwNeSwSe.y += 1.0/384.0;
1392  float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
1393  float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
1394  float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
1395  float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
1396 /*--------------------------------------------------------------------------*/
1397  float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
1398  #if (FXAA_GREEN_AS_LUMA == 0)
1399  float lumaMinM = min(lumaMin, rgbyM.w);
1400  float lumaMaxM = max(lumaMax, rgbyM.w);
1401  #else
1402  float lumaMinM = min(lumaMin, rgbyM.y);
1403  float lumaMaxM = max(lumaMax, rgbyM.y);
1404  #endif
1405  if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
1406 /*--------------------------------------------------------------------------*/
1407  float2 dir;
1408  dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
1409  dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
1410  dir = normalize(dir);
1411 /*--------------------------------------------------------------------------*/
1412  float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
1413 /*--------------------------------------------------------------------------*/
1414  float4 dir2;
1415  float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
1416  dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
1417  dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
1418 /*--------------------------------------------------------------------------*/
1419  float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
1420  float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
1421  float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
1422  float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
1423 /*--------------------------------------------------------------------------*/
1424  float4 rgbyA = rgbyN1 + rgbyP1;
1425  float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;
1426 /*--------------------------------------------------------------------------*/
1427  float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB;
1428  rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA;
1429  return rgbyR; }
1430 /*==========================================================================*/
1431 #endif
1432 
1433 
1434 
1435 /*============================================================================
1436 
1437  FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT)
1438 
1439 ==============================================================================
1440 The code below does not exactly match the assembly.
1441 I have a feeling that 12 cycles is possible, but was not able to get there.
1442 Might have to increase register count to get full performance.
1443 Note this shader does not use perspective interpolation.
1444 
1445 Use the following cgc options,
1446 
1447  --fenable-bx2 --fastmath --fastprecision --nofloatbindings
1448 
1449 ------------------------------------------------------------------------------
1450  NVSHADERPERF OUTPUT
1451 ------------------------------------------------------------------------------
1452 For reference and to aid in debug, output of NVShaderPerf should match this,
1453 
1454 Shader to schedule:
1455  0: texpkb h0.w(TRUE), v5.zyxx, #0
1456  2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
1457  4: texpkb h0.w(TRUE), v5.xwxx, #0
1458  6: addh h0.z(TRUE), -h2, h0.w
1459  7: texpkb h1.w(TRUE), v5, #0
1460  9: addh h0.x(TRUE), h0.z, -h1.w
1461  10: addh h3.w(TRUE), h0.z, h1
1462  11: texpkb h2.w(TRUE), v5.zwzz, #0
1463  13: addh h0.z(TRUE), h3.w, -h2.w
1464  14: addh h0.x(TRUE), h2.w, h0
1465  15: nrmh h1.xz(TRUE), h0_n
1466  16: minh_m8 h0.x(TRUE), |h1|, |h1.z|
1467  17: maxh h4.w(TRUE), h0, h1
1468  18: divx h2.xy(TRUE), h1_n.xzzw, h0_n
1469  19: movr r1.zw(TRUE), v4.xxxy
1470  20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww
1471  22: minh h5.w(TRUE), h0, h1
1472  23: texpkb h0(TRUE), r2.xzxx, #0
1473  25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1
1474  27: maxh h4.x(TRUE), h2.z, h2.w
1475  28: texpkb h1(TRUE), r0.zwzz, #0
1476  30: addh_d2 h1(TRUE), h0, h1
1477  31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
1478  33: texpkb h0(TRUE), r0, #0
1479  35: minh h4.z(TRUE), h2, h2.w
1480  36: fenct TRUE
1481  37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
1482  39: texpkb h2(TRUE), r1, #0
1483  41: addh_d2 h0(TRUE), h0, h2
1484  42: maxh h2.w(TRUE), h4, h4.x
1485  43: minh h2.x(TRUE), h5.w, h4.z
1486  44: addh_d2 h0(TRUE), h0, h1
1487  45: slth h2.x(TRUE), h0.w, h2
1488  46: sgth h2.w(TRUE), h0, h2
1489  47: movh h0(TRUE), h0
1490  48: addx.c0 rc(TRUE), h2, h2.w
1491  49: movh h0(c0.NE.x), h1
1492 
1493 IPU0 ------ Simplified schedule: --------
1494 Pass | Unit | uOp | PC: Op
1495 -----+--------+------+-------------------------
1496  1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
1497  | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
1498  | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-;
1499  | | |
1500  2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
1501  | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
1502  | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-;
1503  | | |
1504  3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0;
1505  | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0;
1506  | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---;
1507  | SCB1 | add | 10: ADDh h3.w, h0.---z, h1;
1508  | | |
1509  4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
1510  | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
1511  | SCB0 | add | 14: ADDh h0.x, h2.w---, h0;
1512  | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-;
1513  | | |
1514  5 | SCT1 | mov | 15: NRMh h1.xz, h0;
1515  | SRB | nrm | 15: NRMh h1.xz, h0;
1516  | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|;
1517  | SCB1 | max | 17: MAXh h4.w, h0, h1;
1518  | | |
1519  6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0;
1520  | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy;
1521  | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-;
1522  | SCB1 | min | 22: MINh h5.w, h0, h1;
1523  | | |
1524  7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0;
1525  | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0;
1526  | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---;
1527  | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1;
1528  | | |
1529  8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0;
1530  | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0;
1531  | SCB0/1 | add | 30: ADDh/2 h1, h0, h1;
1532  | | |
1533  9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--;
1534  | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0;
1535  | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0;
1536  | SCB1 | min | 35: MINh h4.z, h2, h2.--w-;
1537  | | |
1538  10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--;
1539  | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0;
1540  | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0;
1541  | SCB0/1 | add | 41: ADDh/2 h0, h0, h2;
1542  | | |
1543  11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---;
1544  | SCT1 | max | 42: MAXh h2.w, h4, h4.---x;
1545  | SCB0/1 | add | 44: ADDh/2 h0, h0, h1;
1546  | | |
1547  12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2;
1548  | SCT1 | set | 46: SGTh h2.w, h0, h2;
1549  | SCB0/1 | mul | 47: MOVh h0, h0;
1550  | | |
1551  13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---;
1552  | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1;
1553 
1554 Pass SCT TEX SCB
1555  1: 0% 100% 25%
1556  2: 0% 100% 25%
1557  3: 0% 100% 50%
1558  4: 0% 100% 50%
1559  5: 0% 0% 50%
1560  6: 100% 0% 75%
1561  7: 0% 100% 75%
1562  8: 0% 100% 100%
1563  9: 0% 100% 25%
1564  10: 0% 100% 100%
1565  11: 50% 0% 100%
1566  12: 50% 0% 100%
1567  13: 25% 0% 100%
1568 
1569 MEAN: 17% 61% 67%
1570 
1571 Pass SCT0 SCT1 TEX SCB0 SCB1
1572  1: 0% 0% 100% 0% 100%
1573  2: 0% 0% 100% 0% 100%
1574  3: 0% 0% 100% 100% 100%
1575  4: 0% 0% 100% 100% 100%
1576  5: 0% 0% 0% 100% 100%
1577  6: 100% 100% 0% 100% 100%
1578  7: 0% 0% 100% 100% 100%
1579  8: 0% 0% 100% 100% 100%
1580  9: 0% 0% 100% 0% 100%
1581  10: 0% 0% 100% 100% 100%
1582  11: 100% 100% 0% 100% 100%
1583  12: 100% 100% 0% 100% 100%
1584  13: 100% 0% 0% 100% 100%
1585 
1586 MEAN: 30% 23% 61% 76% 100%
1587 Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
1588 Results 13 cycles, 3 r regs, 923,076,923 pixels/s
1589 ============================================================================*/
1590 #if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0)
1591 /*--------------------------------------------------------------------------*/
1592 #pragma regcount 7
1593 #pragma disablepc all
1594 #pragma option O3
1595 #pragma option OutColorPrec=fp16
1596 #pragma texformat default RGBA8
1597 /*==========================================================================*/
1598 half4 FxaaPixelShader(
1599  // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1600  FxaaFloat2 pos,
1601  FxaaFloat4 fxaaConsolePosPos,
1602  FxaaTex tex,
1603  FxaaTex fxaaConsole360TexExpBiasNegOne,
1604  FxaaTex fxaaConsole360TexExpBiasNegTwo,
1605  FxaaFloat2 fxaaQualityRcpFrame,
1606  FxaaFloat4 fxaaConsoleRcpFrameOpt,
1607  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1608  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1609  FxaaFloat fxaaQualitySubpix,
1610  FxaaFloat fxaaQualityEdgeThreshold,
1611  FxaaFloat fxaaQualityEdgeThresholdMin,
1612  FxaaFloat fxaaConsoleEdgeSharpness,
1613  FxaaFloat fxaaConsoleEdgeThreshold,
1614  FxaaFloat fxaaConsoleEdgeThresholdMin,
1615  FxaaFloat4 fxaaConsole360ConstDir
1616 ) {
1617 /*--------------------------------------------------------------------------*/
1618 // (1)
1619  half4 dir;
1620  half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
1621  #if (FXAA_GREEN_AS_LUMA == 0)
1622  lumaNe.w += half(1.0/512.0);
1623  dir.x = -lumaNe.w;
1624  dir.z = -lumaNe.w;
1625  #else
1626  lumaNe.y += half(1.0/512.0);
1627  dir.x = -lumaNe.y;
1628  dir.z = -lumaNe.y;
1629  #endif
1630 /*--------------------------------------------------------------------------*/
1631 // (2)
1632  half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
1633  #if (FXAA_GREEN_AS_LUMA == 0)
1634  dir.x += lumaSw.w;
1635  dir.z += lumaSw.w;
1636  #else
1637  dir.x += lumaSw.y;
1638  dir.z += lumaSw.y;
1639  #endif
1640 /*--------------------------------------------------------------------------*/
1641 // (3)
1642  half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
1643  #if (FXAA_GREEN_AS_LUMA == 0)
1644  dir.x -= lumaNw.w;
1645  dir.z += lumaNw.w;
1646  #else
1647  dir.x -= lumaNw.y;
1648  dir.z += lumaNw.y;
1649  #endif
1650 /*--------------------------------------------------------------------------*/
1651 // (4)
1652  half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
1653  #if (FXAA_GREEN_AS_LUMA == 0)
1654  dir.x += lumaSe.w;
1655  dir.z -= lumaSe.w;
1656  #else
1657  dir.x += lumaSe.y;
1658  dir.z -= lumaSe.y;
1659  #endif
1660 /*--------------------------------------------------------------------------*/
1661 // (5)
1662  half4 dir1_pos;
1663  dir1_pos.xy = normalize(dir.xyz).xz;
1664  half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
1665 /*--------------------------------------------------------------------------*/
1666 // (6)
1667  half4 dir2_pos;
1668  dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
1669  dir1_pos.zw = pos.xy;
1670  dir2_pos.zw = pos.xy;
1671  half4 temp1N;
1672  temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
1673 /*--------------------------------------------------------------------------*/
1674 // (7)
1675  temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
1676  half4 rgby1;
1677  rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
1678 /*--------------------------------------------------------------------------*/
1679 // (8)
1680  rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
1681  rgby1 = (temp1N + rgby1) * 0.5;
1682 /*--------------------------------------------------------------------------*/
1683 // (9)
1684  half4 temp2N;
1685  temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
1686  temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
1687 /*--------------------------------------------------------------------------*/
1688 // (10)
1689  half4 rgby2;
1690  rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
1691  rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
1692  rgby2 = (temp2N + rgby2) * 0.5;
1693 /*--------------------------------------------------------------------------*/
1694 // (11)
1695  // compilier moves these scalar ops up to other cycles
1696  #if (FXAA_GREEN_AS_LUMA == 0)
1697  half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
1698  half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
1699  #else
1700  half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));
1701  half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));
1702  #endif
1703  rgby2 = (rgby2 + rgby1) * 0.5;
1704 /*--------------------------------------------------------------------------*/
1705 // (12)
1706  #if (FXAA_GREEN_AS_LUMA == 0)
1707  bool twoTapLt = rgby2.w < lumaMin;
1708  bool twoTapGt = rgby2.w > lumaMax;
1709  #else
1710  bool twoTapLt = rgby2.y < lumaMin;
1711  bool twoTapGt = rgby2.y > lumaMax;
1712  #endif
1713 /*--------------------------------------------------------------------------*/
1714 // (13)
1715  if(twoTapLt || twoTapGt) rgby2 = rgby1;
1716 /*--------------------------------------------------------------------------*/
1717  return rgby2; }
1718 /*==========================================================================*/
1719 #endif
1720 
1721 
1722 
1723 /*============================================================================
1724 
1725  FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT)
1726 
1727 ==============================================================================
1728 The code mostly matches the assembly.
1729 I have a feeling that 14 cycles is possible, but was not able to get there.
1730 Might have to increase register count to get full performance.
1731 Note this shader does not use perspective interpolation.
1732 
1733 Use the following cgc options,
1734 
1735  --fenable-bx2 --fastmath --fastprecision --nofloatbindings
1736 
1737 Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks).
1738 Will look at fixing this for FXAA 3.12.
1739 ------------------------------------------------------------------------------
1740  NVSHADERPERF OUTPUT
1741 ------------------------------------------------------------------------------
1742 For reference and to aid in debug, output of NVShaderPerf should match this,
1743 
1744 Shader to schedule:
1745  0: texpkb h0.w(TRUE), v5.zyxx, #0
1746  2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
1747  4: texpkb h1.w(TRUE), v5.xwxx, #0
1748  6: addh h0.x(TRUE), h1.w, -h2.y
1749  7: texpkb h2.w(TRUE), v5.zwzz, #0
1750  9: minh h4.w(TRUE), h2.y, h2
1751  10: maxh h5.x(TRUE), h2.y, h2.w
1752  11: texpkb h0.w(TRUE), v5, #0
1753  13: addh h3.w(TRUE), -h0, h0.x
1754  14: addh h0.x(TRUE), h0.w, h0
1755  15: addh h0.z(TRUE), -h2.w, h0.x
1756  16: addh h0.x(TRUE), h2.w, h3.w
1757  17: minh h5.y(TRUE), h0.w, h1.w
1758  18: nrmh h2.xz(TRUE), h0_n
1759  19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z|
1760  20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w
1761  21: movr r1.zw(TRUE), v4.xxxy
1762  22: maxh h2.w(TRUE), h0, h1
1763  23: fenct TRUE
1764  24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
1765  26: texpkb h0(TRUE), r0, #0
1766  28: maxh h5.x(TRUE), h2.w, h5
1767  29: minh h5.w(TRUE), h5.y, h4
1768  30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
1769  32: texpkb h2(TRUE), r1, #0
1770  34: addh_d2 h2(TRUE), h0, h2
1771  35: texpkb h1(TRUE), v4, #0
1772  37: maxh h5.y(TRUE), h5.x, h1.w
1773  38: minh h4.w(TRUE), h1, h5
1774  39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
1775  41: texpkb h0(TRUE), r0, #0
1776  43: addh_m8 h5.z(TRUE), h5.y, -h4.w
1777  44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
1778  46: texpkb h3(TRUE), r2, #0
1779  48: addh_d2 h0(TRUE), h0, h3
1780  49: addh_d2 h3(TRUE), h0, h2
1781  50: movh h0(TRUE), h3
1782  51: slth h3.x(TRUE), h3.w, h5.w
1783  52: sgth h3.w(TRUE), h3, h5.x
1784  53: addx.c0 rc(TRUE), h3.x, h3
1785  54: slth.c0 rc(TRUE), h5.z, h5
1786  55: movh h0(c0.NE.w), h2
1787  56: movh h0(c0.NE.x), h1
1788 
1789 IPU0 ------ Simplified schedule: --------
1790 Pass | Unit | uOp | PC: Op
1791 -----+--------+------+-------------------------
1792  1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
1793  | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
1794  | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--;
1795  | | |
1796  2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
1797  | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
1798  | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---;
1799  | | |
1800  3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
1801  | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
1802  | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---;
1803  | SCB1 | min | 9: MINh h4.w, h2.---y, h2;
1804  | | |
1805  4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0;
1806  | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0;
1807  | SCB0 | add | 14: ADDh h0.x, h0.w---, h0;
1808  | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x;
1809  | | |
1810  5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---;
1811  | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-;
1812  | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--;
1813  | | |
1814  6 | SCT1 | mov | 18: NRMh h2.xz, h0;
1815  | SRB | nrm | 18: NRMh h2.xz, h0;
1816  | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|;
1817  | | |
1818  7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--;
1819  | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy;
1820  | SCB1 | max | 22: MAXh h2.w, h0, h1;
1821  | | |
1822  8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--;
1823  | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0;
1824  | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0;
1825  | SCB0 | max | 28: MAXh h5.x, h2.w---, h5;
1826  | SCB1 | min | 29: MINh h5.w, h5.---y, h4;
1827  | | |
1828  9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--;
1829  | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0;
1830  | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0;
1831  | SCB0/1 | add | 34: ADDh/2 h2, h0, h2;
1832  | | |
1833  10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0;
1834  | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0;
1835  | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--;
1836  | SCB1 | min | 38: MINh h4.w, h1, h5;
1837  | | |
1838  11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--;
1839  | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0;
1840  | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0;
1841  | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--;
1842  | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-;
1843  | | |
1844  12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0;
1845  | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0;
1846  | SCB0/1 | add | 48: ADDh/2 h0, h0, h3;
1847  | | |
1848  13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2;
1849  | SCB0/1 | mul | 50: MOVh h0, h3;
1850  | | |
1851  14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---;
1852  | SCT1 | set | 52: SGTh h3.w, h3, h5.---x;
1853  | SCB0 | set | 54: SLThc0 rc, h5.z---, h5;
1854  | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3;
1855  | | |
1856  15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2;
1857  | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1;
1858 
1859 Pass SCT TEX SCB
1860  1: 0% 100% 25%
1861  2: 0% 100% 25%
1862  3: 0% 100% 50%
1863  4: 0% 100% 50%
1864  5: 50% 0% 25%
1865  6: 0% 0% 25%
1866  7: 100% 0% 25%
1867  8: 0% 100% 50%
1868  9: 0% 100% 100%
1869  10: 0% 100% 50%
1870  11: 0% 100% 75%
1871  12: 0% 100% 100%
1872  13: 100% 0% 100%
1873  14: 50% 0% 50%
1874  15: 100% 0% 100%
1875 
1876 MEAN: 26% 60% 56%
1877 
1878 Pass SCT0 SCT1 TEX SCB0 SCB1
1879  1: 0% 0% 100% 100% 0%
1880  2: 0% 0% 100% 100% 0%
1881  3: 0% 0% 100% 100% 100%
1882  4: 0% 0% 100% 100% 100%
1883  5: 100% 100% 0% 100% 0%
1884  6: 0% 0% 0% 0% 100%
1885  7: 100% 100% 0% 0% 100%
1886  8: 0% 0% 100% 100% 100%
1887  9: 0% 0% 100% 100% 100%
1888  10: 0% 0% 100% 100% 100%
1889  11: 0% 0% 100% 100% 100%
1890  12: 0% 0% 100% 100% 100%
1891  13: 100% 100% 0% 100% 100%
1892  14: 100% 100% 0% 100% 100%
1893  15: 100% 100% 0% 100% 100%
1894 
1895 MEAN: 33% 33% 60% 86% 80%
1896 Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
1897 Results 15 cycles, 3 r regs, 800,000,000 pixels/s
1898 ============================================================================*/
1899 #if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1)
1900 /*--------------------------------------------------------------------------*/
1901 #pragma regcount 7
1902 #pragma disablepc all
1903 #pragma option O2
1904 #pragma option OutColorPrec=fp16
1905 #pragma texformat default RGBA8
1906 /*==========================================================================*/
1907 half4 FxaaPixelShader(
1908  // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
1909  FxaaFloat2 pos,
1910  FxaaFloat4 fxaaConsolePosPos,
1911  FxaaTex tex,
1912  FxaaTex fxaaConsole360TexExpBiasNegOne,
1913  FxaaTex fxaaConsole360TexExpBiasNegTwo,
1914  FxaaFloat2 fxaaQualityRcpFrame,
1915  FxaaFloat4 fxaaConsoleRcpFrameOpt,
1916  FxaaFloat4 fxaaConsoleRcpFrameOpt2,
1917  FxaaFloat4 fxaaConsole360RcpFrameOpt2,
1918  FxaaFloat fxaaQualitySubpix,
1919  FxaaFloat fxaaQualityEdgeThreshold,
1920  FxaaFloat fxaaQualityEdgeThresholdMin,
1921  FxaaFloat fxaaConsoleEdgeSharpness,
1922  FxaaFloat fxaaConsoleEdgeThreshold,
1923  FxaaFloat fxaaConsoleEdgeThresholdMin,
1924  FxaaFloat4 fxaaConsole360ConstDir
1925 ) {
1926 /*--------------------------------------------------------------------------*/
1927 // (1)
1928  half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
1929  #if (FXAA_GREEN_AS_LUMA == 0)
1930  half lumaNe = rgbyNe.w + half(1.0/512.0);
1931  #else
1932  half lumaNe = rgbyNe.y + half(1.0/512.0);
1933  #endif
1934 /*--------------------------------------------------------------------------*/
1935 // (2)
1936  half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
1937  #if (FXAA_GREEN_AS_LUMA == 0)
1938  half lumaSwNegNe = lumaSw.w - lumaNe;
1939  #else
1940  half lumaSwNegNe = lumaSw.y - lumaNe;
1941  #endif
1942 /*--------------------------------------------------------------------------*/
1943 // (3)
1944  half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
1945  #if (FXAA_GREEN_AS_LUMA == 0)
1946  half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);
1947  half lumaMinNwSw = min(lumaNw.w, lumaSw.w);
1948  #else
1949  half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);
1950  half lumaMinNwSw = min(lumaNw.y, lumaSw.y);
1951  #endif
1952 /*--------------------------------------------------------------------------*/
1953 // (4)
1954  half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
1955  #if (FXAA_GREEN_AS_LUMA == 0)
1956  half dirZ = lumaNw.w + lumaSwNegNe;
1957  half dirX = -lumaNw.w + lumaSwNegNe;
1958  #else
1959  half dirZ = lumaNw.y + lumaSwNegNe;
1960  half dirX = -lumaNw.y + lumaSwNegNe;
1961  #endif
1962 /*--------------------------------------------------------------------------*/
1963 // (5)
1964  half3 dir;
1965  dir.y = 0.0;
1966  #if (FXAA_GREEN_AS_LUMA == 0)
1967  dir.x = lumaSe.w + dirX;
1968  dir.z = -lumaSe.w + dirZ;
1969  half lumaMinNeSe = min(lumaNe, lumaSe.w);
1970  #else
1971  dir.x = lumaSe.y + dirX;
1972  dir.z = -lumaSe.y + dirZ;
1973  half lumaMinNeSe = min(lumaNe, lumaSe.y);
1974  #endif
1975 /*--------------------------------------------------------------------------*/
1976 // (6)
1977  half4 dir1_pos;
1978  dir1_pos.xy = normalize(dir).xz;
1979  half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
1980 /*--------------------------------------------------------------------------*/
1981 // (7)
1982  half4 dir2_pos;
1983  dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));
1984  dir1_pos.zw = pos.xy;
1985  dir2_pos.zw = pos.xy;
1986  #if (FXAA_GREEN_AS_LUMA == 0)
1987  half lumaMaxNeSe = max(lumaNe, lumaSe.w);
1988  #else
1989  half lumaMaxNeSe = max(lumaNe, lumaSe.y);
1990  #endif
1991 /*--------------------------------------------------------------------------*/
1992 // (8)
1993  half4 temp1N;
1994  temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
1995  temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
1996  half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);
1997  half lumaMin = min(lumaMinNwSw, lumaMinNeSe);
1998 /*--------------------------------------------------------------------------*/
1999 // (9)
2000  half4 rgby1;
2001  rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
2002  rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
2003  rgby1 = (temp1N + rgby1) * 0.5;
2004 /*--------------------------------------------------------------------------*/
2005 // (10)
2006  half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));
2007  #if (FXAA_GREEN_AS_LUMA == 0)
2008  half lumaMaxM = max(lumaMax, rgbyM.w);
2009  half lumaMinM = min(lumaMin, rgbyM.w);
2010  #else
2011  half lumaMaxM = max(lumaMax, rgbyM.y);
2012  half lumaMinM = min(lumaMin, rgbyM.y);
2013  #endif
2014 /*--------------------------------------------------------------------------*/
2015 // (11)
2016  half4 temp2N;
2017  temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
2018  temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
2019  half4 rgby2;
2020  rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
2021  half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;
2022 /*--------------------------------------------------------------------------*/
2023 // (12)
2024  rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
2025  rgby2 = (temp2N + rgby2) * 0.5;
2026 /*--------------------------------------------------------------------------*/
2027 // (13)
2028  rgby2 = (rgby2 + rgby1) * 0.5;
2029 /*--------------------------------------------------------------------------*/
2030 // (14)
2031  #if (FXAA_GREEN_AS_LUMA == 0)
2032  bool twoTapLt = rgby2.w < lumaMin;
2033  bool twoTapGt = rgby2.w > lumaMax;
2034  #else
2035  bool twoTapLt = rgby2.y < lumaMin;
2036  bool twoTapGt = rgby2.y > lumaMax;
2037  #endif
2038  bool earlyExit = lumaRangeM < lumaMax;
2039  bool twoTap = twoTapLt || twoTapGt;
2040 /*--------------------------------------------------------------------------*/
2041 // (15)
2042  if(twoTap) rgby2 = rgby1;
2043  if(earlyExit) rgby2 = rgbyM;
2044 /*--------------------------------------------------------------------------*/
2045  return rgby2; }
2046 /*==========================================================================*/
2047 #endif