Fxaa.glsl
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 #version 430 core 174 175 layout(local_size_x = 16, local_size_y = 16) in; 176 layout(rgba8, binding = 0, set = 3) uniform image2D imgOutput; 177 178 layout(binding = 1, set = 2) uniform sampler2D inputImage; 179 layout(binding = 2) uniform invResolution 180 { 181 vec2 invResolution_data; 182 }; 183 184 #define FXAA_QUALITY_PRESET 12 185 #define FXAA_GREEN_AS_LUMA 1 186 #define FXAA_PC 1 187 #define FXAA_GLSL_130 1 188 189 190 /*============================================================================ 191 192 INTEGRATION KNOBS 193 194 /*==========================================================================*/ 195 #ifndef FXAA_PC 196 // 197 // FXAA Quality 198 // The high quality PC algorithm. 199 // 200 #define FXAA_PC 0 201 #endif 202 /*--------------------------------------------------------------------------*/ 203 #ifndef FXAA_GLSL_120 204 #define FXAA_GLSL_120 0 205 #endif 206 /*--------------------------------------------------------------------------*/ 207 #ifndef FXAA_GLSL_130 208 #define FXAA_GLSL_130 0 209 #endif 210 /*==========================================================================*/ 211 #ifndef FXAA_GREEN_AS_LUMA 212 // 213 // For those using non-linear color, 214 // and either not able to get luma in alpha, or not wanting to, 215 // this enables FXAA to run using green as a proxy for luma. 216 // So with this enabled, no need to pack luma in alpha. 217 // 218 // This will turn off AA on anything which lacks some amount of green. 219 // Pure red and blue or combination of only R and B, will get no AA. 220 // 221 // Might want to lower the settings for both, 222 // fxaaConsoleEdgeThresholdMin 223 // fxaaQualityEdgeThresholdMin 224 // In order to insure AA does not get turned off on colors 225 // which contain a minor amount of green. 226 // 227 // 1 = On. 228 // 0 = Off. 229 // 230 #define FXAA_GREEN_AS_LUMA 0 231 #endif 232 /*--------------------------------------------------------------------------*/ 233 #ifndef FXAA_EARLY_EXIT 234 // 235 // Controls algorithm's early exit path. 236 // On PS3 turning this ON adds 2 cycles to the shader. 237 // On 360 turning this OFF adds 10ths of a millisecond to the shader. 238 // Turning this off on console will result in a more blurry image. 239 // So this defaults to on. 240 // 241 // 1 = On. 242 // 0 = Off. 243 // 244 #define FXAA_EARLY_EXIT 1 245 #endif 246 /*--------------------------------------------------------------------------*/ 247 #ifndef FXAA_DISCARD 248 // 249 // Only valid for PC OpenGL currently. 250 // Probably will not work when FXAA_GREEN_AS_LUMA = 1. 251 // 252 // 1 = Use discard on pixels which don't need AA. 253 // For APIs which enable concurrent TEX+ROP from same surface. 254 // 0 = Return unchanged color on pixels which don't need AA. 255 // 256 #define FXAA_DISCARD 0 257 #endif 258 /*--------------------------------------------------------------------------*/ 259 #ifndef FXAA_FAST_PIXEL_OFFSET 260 // 261 // Used for GLSL 120 only. 262 // 263 // 1 = GL API supports fast pixel offsets 264 // 0 = do not use fast pixel offsets 265 // 266 #ifdef GL_EXT_gpu_shader4 267 #define FXAA_FAST_PIXEL_OFFSET 1 268 #endif 269 #ifdef GL_NV_gpu_shader5 270 #define FXAA_FAST_PIXEL_OFFSET 1 271 #endif 272 #ifdef GL_ARB_gpu_shader5 273 #define FXAA_FAST_PIXEL_OFFSET 1 274 #endif 275 #ifndef FXAA_FAST_PIXEL_OFFSET 276 #define FXAA_FAST_PIXEL_OFFSET 0 277 #endif 278 #endif 279 /*--------------------------------------------------------------------------*/ 280 #ifndef FXAA_GATHER4_ALPHA 281 // 282 // 1 = API supports gather4 on alpha channel. 283 // 0 = API does not support gather4 on alpha channel. 284 // 285 #if (FXAA_HLSL_5 == 1) 286 #define FXAA_GATHER4_ALPHA 1 287 #endif 288 #ifdef GL_ARB_gpu_shader5 289 #define FXAA_GATHER4_ALPHA 1 290 #endif 291 #ifdef GL_NV_gpu_shader5 292 #define FXAA_GATHER4_ALPHA 1 293 #endif 294 #ifndef FXAA_GATHER4_ALPHA 295 #define FXAA_GATHER4_ALPHA 0 296 #endif 297 #endif 298 299 /*============================================================================ 300 FXAA QUALITY - TUNING KNOBS 301 ------------------------------------------------------------------------------ 302 NOTE the other tuning knobs are now in the shader function inputs! 303 ============================================================================*/ 304 #ifndef FXAA_QUALITY_PRESET 305 // 306 // Choose the quality preset. 307 // This needs to be compiled into the shader as it effects code. 308 // Best option to include multiple presets is to 309 // in each shader define the preset, then include this file. 310 // 311 // OPTIONS 312 // ----------------------------------------------------------------------- 313 // 10 to 15 - default medium dither (10=fastest, 15=highest quality) 314 // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) 315 // 39 - no dither, very expensive 316 // 317 // NOTES 318 // ----------------------------------------------------------------------- 319 // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) 320 // 13 = about same speed as FXAA 3.9 and better than 12 321 // 23 = closest to FXAA 3.9 visually and performance wise 322 // _ = the lowest digit is directly related to performance 323 // _ = the highest digit is directly related to style 324 // 325 #define FXAA_QUALITY_PRESET 12 326 #endif 327 328 329 /*============================================================================ 330 331 FXAA QUALITY - PRESETS 332 333 ============================================================================*/ 334 335 /*============================================================================ 336 FXAA QUALITY - MEDIUM DITHER PRESETS 337 ============================================================================*/ 338 #if (FXAA_QUALITY_PRESET == 10) 339 #define FXAA_QUALITY_PS 3 340 #define FXAA_QUALITY_P0 1.5 341 #define FXAA_QUALITY_P1 3.0 342 #define FXAA_QUALITY_P2 12.0 343 #endif 344 /*--------------------------------------------------------------------------*/ 345 #if (FXAA_QUALITY_PRESET == 11) 346 #define FXAA_QUALITY_PS 4 347 #define FXAA_QUALITY_P0 1.0 348 #define FXAA_QUALITY_P1 1.5 349 #define FXAA_QUALITY_P2 3.0 350 #define FXAA_QUALITY_P3 12.0 351 #endif 352 /*--------------------------------------------------------------------------*/ 353 #if (FXAA_QUALITY_PRESET == 12) 354 #define FXAA_QUALITY_PS 5 355 #define FXAA_QUALITY_P0 1.0 356 #define FXAA_QUALITY_P1 1.5 357 #define FXAA_QUALITY_P2 2.0 358 #define FXAA_QUALITY_P3 4.0 359 #define FXAA_QUALITY_P4 12.0 360 #endif 361 /*--------------------------------------------------------------------------*/ 362 #if (FXAA_QUALITY_PRESET == 13) 363 #define FXAA_QUALITY_PS 6 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 4.0 369 #define FXAA_QUALITY_P5 12.0 370 #endif 371 /*--------------------------------------------------------------------------*/ 372 #if (FXAA_QUALITY_PRESET == 14) 373 #define FXAA_QUALITY_PS 7 374 #define FXAA_QUALITY_P0 1.0 375 #define FXAA_QUALITY_P1 1.5 376 #define FXAA_QUALITY_P2 2.0 377 #define FXAA_QUALITY_P3 2.0 378 #define FXAA_QUALITY_P4 2.0 379 #define FXAA_QUALITY_P5 4.0 380 #define FXAA_QUALITY_P6 12.0 381 #endif 382 /*--------------------------------------------------------------------------*/ 383 #if (FXAA_QUALITY_PRESET == 15) 384 #define FXAA_QUALITY_PS 8 385 #define FXAA_QUALITY_P0 1.0 386 #define FXAA_QUALITY_P1 1.5 387 #define FXAA_QUALITY_P2 2.0 388 #define FXAA_QUALITY_P3 2.0 389 #define FXAA_QUALITY_P4 2.0 390 #define FXAA_QUALITY_P5 2.0 391 #define FXAA_QUALITY_P6 4.0 392 #define FXAA_QUALITY_P7 12.0 393 #endif 394 395 /*============================================================================ 396 FXAA QUALITY - LOW DITHER PRESETS 397 ============================================================================*/ 398 #if (FXAA_QUALITY_PRESET == 20) 399 #define FXAA_QUALITY_PS 3 400 #define FXAA_QUALITY_P0 1.5 401 #define FXAA_QUALITY_P1 2.0 402 #define FXAA_QUALITY_P2 8.0 403 #endif 404 /*--------------------------------------------------------------------------*/ 405 #if (FXAA_QUALITY_PRESET == 21) 406 #define FXAA_QUALITY_PS 4 407 #define FXAA_QUALITY_P0 1.0 408 #define FXAA_QUALITY_P1 1.5 409 #define FXAA_QUALITY_P2 2.0 410 #define FXAA_QUALITY_P3 8.0 411 #endif 412 /*--------------------------------------------------------------------------*/ 413 #if (FXAA_QUALITY_PRESET == 22) 414 #define FXAA_QUALITY_PS 5 415 #define FXAA_QUALITY_P0 1.0 416 #define FXAA_QUALITY_P1 1.5 417 #define FXAA_QUALITY_P2 2.0 418 #define FXAA_QUALITY_P3 2.0 419 #define FXAA_QUALITY_P4 8.0 420 #endif 421 /*--------------------------------------------------------------------------*/ 422 #if (FXAA_QUALITY_PRESET == 23) 423 #define FXAA_QUALITY_PS 6 424 #define FXAA_QUALITY_P0 1.0 425 #define FXAA_QUALITY_P1 1.5 426 #define FXAA_QUALITY_P2 2.0 427 #define FXAA_QUALITY_P3 2.0 428 #define FXAA_QUALITY_P4 2.0 429 #define FXAA_QUALITY_P5 8.0 430 #endif 431 /*--------------------------------------------------------------------------*/ 432 #if (FXAA_QUALITY_PRESET == 24) 433 #define FXAA_QUALITY_PS 7 434 #define FXAA_QUALITY_P0 1.0 435 #define FXAA_QUALITY_P1 1.5 436 #define FXAA_QUALITY_P2 2.0 437 #define FXAA_QUALITY_P3 2.0 438 #define FXAA_QUALITY_P4 2.0 439 #define FXAA_QUALITY_P5 3.0 440 #define FXAA_QUALITY_P6 8.0 441 #endif 442 /*--------------------------------------------------------------------------*/ 443 #if (FXAA_QUALITY_PRESET == 25) 444 #define FXAA_QUALITY_PS 8 445 #define FXAA_QUALITY_P0 1.0 446 #define FXAA_QUALITY_P1 1.5 447 #define FXAA_QUALITY_P2 2.0 448 #define FXAA_QUALITY_P3 2.0 449 #define FXAA_QUALITY_P4 2.0 450 #define FXAA_QUALITY_P5 2.0 451 #define FXAA_QUALITY_P6 4.0 452 #define FXAA_QUALITY_P7 8.0 453 #endif 454 /*--------------------------------------------------------------------------*/ 455 #if (FXAA_QUALITY_PRESET == 26) 456 #define FXAA_QUALITY_PS 9 457 #define FXAA_QUALITY_P0 1.0 458 #define FXAA_QUALITY_P1 1.5 459 #define FXAA_QUALITY_P2 2.0 460 #define FXAA_QUALITY_P3 2.0 461 #define FXAA_QUALITY_P4 2.0 462 #define FXAA_QUALITY_P5 2.0 463 #define FXAA_QUALITY_P6 2.0 464 #define FXAA_QUALITY_P7 4.0 465 #define FXAA_QUALITY_P8 8.0 466 #endif 467 /*--------------------------------------------------------------------------*/ 468 #if (FXAA_QUALITY_PRESET == 27) 469 #define FXAA_QUALITY_PS 10 470 #define FXAA_QUALITY_P0 1.0 471 #define FXAA_QUALITY_P1 1.5 472 #define FXAA_QUALITY_P2 2.0 473 #define FXAA_QUALITY_P3 2.0 474 #define FXAA_QUALITY_P4 2.0 475 #define FXAA_QUALITY_P5 2.0 476 #define FXAA_QUALITY_P6 2.0 477 #define FXAA_QUALITY_P7 2.0 478 #define FXAA_QUALITY_P8 4.0 479 #define FXAA_QUALITY_P9 8.0 480 #endif 481 /*--------------------------------------------------------------------------*/ 482 #if (FXAA_QUALITY_PRESET == 28) 483 #define FXAA_QUALITY_PS 11 484 #define FXAA_QUALITY_P0 1.0 485 #define FXAA_QUALITY_P1 1.5 486 #define FXAA_QUALITY_P2 2.0 487 #define FXAA_QUALITY_P3 2.0 488 #define FXAA_QUALITY_P4 2.0 489 #define FXAA_QUALITY_P5 2.0 490 #define FXAA_QUALITY_P6 2.0 491 #define FXAA_QUALITY_P7 2.0 492 #define FXAA_QUALITY_P8 2.0 493 #define FXAA_QUALITY_P9 4.0 494 #define FXAA_QUALITY_P10 8.0 495 #endif 496 /*--------------------------------------------------------------------------*/ 497 #if (FXAA_QUALITY_PRESET == 29) 498 #define FXAA_QUALITY_PS 12 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 2.0 505 #define FXAA_QUALITY_P6 2.0 506 #define FXAA_QUALITY_P7 2.0 507 #define FXAA_QUALITY_P8 2.0 508 #define FXAA_QUALITY_P9 2.0 509 #define FXAA_QUALITY_P10 4.0 510 #define FXAA_QUALITY_P11 8.0 511 #endif 512 513 /*============================================================================ 514 FXAA QUALITY - EXTREME QUALITY 515 ============================================================================*/ 516 #if (FXAA_QUALITY_PRESET == 39) 517 #define FXAA_QUALITY_PS 12 518 #define FXAA_QUALITY_P0 1.0 519 #define FXAA_QUALITY_P1 1.0 520 #define FXAA_QUALITY_P2 1.0 521 #define FXAA_QUALITY_P3 1.0 522 #define FXAA_QUALITY_P4 1.0 523 #define FXAA_QUALITY_P5 1.5 524 #define FXAA_QUALITY_P6 2.0 525 #define FXAA_QUALITY_P7 2.0 526 #define FXAA_QUALITY_P8 2.0 527 #define FXAA_QUALITY_P9 2.0 528 #define FXAA_QUALITY_P10 4.0 529 #define FXAA_QUALITY_P11 8.0 530 #endif 531 532 533 534 /*============================================================================ 535 536 API PORTING 537 538 ============================================================================*/ 539 #if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) 540 #define FxaaBool bool 541 #define FxaaDiscard discard 542 #define FxaaFloat float 543 #define FxaaFloat2 vec2 544 #define FxaaFloat3 vec3 545 #define FxaaFloat4 vec4 546 #define FxaaHalf float 547 #define FxaaHalf2 vec2 548 #define FxaaHalf3 vec3 549 #define FxaaHalf4 vec4 550 #define FxaaInt2 ivec2 551 #define FxaaSat(x) clamp(x, 0.0, 1.0) 552 #define FxaaTex sampler2D 553 #else 554 #define FxaaBool bool 555 #define FxaaDiscard clip(-1) 556 #define FxaaFloat float 557 #define FxaaFloat2 float2 558 #define FxaaFloat3 float3 559 #define FxaaFloat4 float4 560 #define FxaaHalf half 561 #define FxaaHalf2 half2 562 #define FxaaHalf3 half3 563 #define FxaaHalf4 half4 564 #define FxaaSat(x) saturate(x) 565 #endif 566 /*--------------------------------------------------------------------------*/ 567 #if (FXAA_GLSL_120 == 1) 568 // Requires, 569 // #version 120 570 // And at least, 571 // #extension GL_EXT_gpu_shader4 : enable 572 // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) 573 #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) 574 #if (FXAA_FAST_PIXEL_OFFSET == 1) 575 #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) 576 #else 577 #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) 578 #endif 579 #if (FXAA_GATHER4_ALPHA == 1) 580 // use #extension GL_ARB_gpu_shader5 : enable 581 #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) 582 #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) 583 #define FxaaTexGreen4(t, p) textureGather(t, p, 1) 584 #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) 585 #endif 586 #endif 587 /*--------------------------------------------------------------------------*/ 588 #if (FXAA_GLSL_130 == 1) 589 // Requires "#version 130" or better 590 #define FxaaTexTop(t, p) textureLod(t, p, 0.0) 591 #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) 592 #if (FXAA_GATHER4_ALPHA == 1) 593 // use #extension GL_ARB_gpu_shader5 : enable 594 #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) 595 #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) 596 #define FxaaTexGreen4(t, p) textureGather(t, p, 1) 597 #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) 598 #endif 599 #endif 600 601 602 /*============================================================================ 603 GREEN AS LUMA OPTION SUPPORT FUNCTION 604 ============================================================================*/ 605 #if (FXAA_GREEN_AS_LUMA == 0) 606 FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } 607 #else 608 FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } 609 #endif 610 611 612 613 614 /*============================================================================ 615 616 FXAA3 QUALITY - PC 617 618 ============================================================================*/ 619 #if (FXAA_PC == 1) 620 /*--------------------------------------------------------------------------*/ 621 FxaaFloat4 FxaaPixelShader( 622 // 623 // Use noperspective interpolation here (turn off perspective interpolation). 624 // {xy} = center of pixel 625 FxaaFloat2 pos, 626 // 627 // Used only for FXAA Console, and not used on the 360 version. 628 // Use noperspective interpolation here (turn off perspective interpolation). 629 // {xy_} = upper left of pixel 630 // {_zw} = lower right of pixel 631 FxaaFloat4 fxaaConsolePosPos, 632 // 633 // Input color texture. 634 // {rgb_} = color in linear or perceptual color space 635 // if (FXAA_GREEN_AS_LUMA == 0) 636 // {__a} = luma in perceptual color space (not linear) 637 FxaaTex tex, 638 // 639 // Only used on the optimized 360 version of FXAA Console. 640 // For everything but 360, just use the same input here as for "tex". 641 // For 360, same texture, just alias with a 2nd sampler. 642 // This sampler needs to have an exponent bias of -1. 643 FxaaTex fxaaConsole360TexExpBiasNegOne, 644 // 645 // Only used on the optimized 360 version of FXAA Console. 646 // For everything but 360, just use the same input here as for "tex". 647 // For 360, same texture, just alias with a 3nd sampler. 648 // This sampler needs to have an exponent bias of -2. 649 FxaaTex fxaaConsole360TexExpBiasNegTwo, 650 // 651 // Only used on FXAA Quality. 652 // This must be from a constant/uniform. 653 // {x_} = 1.0/screenWidthInPixels 654 // {_y} = 1.0/screenHeightInPixels 655 FxaaFloat2 fxaaQualityRcpFrame, 656 // 657 // Only used on FXAA Console. 658 // This must be from a constant/uniform. 659 // This effects sub-pixel AA quality and inversely sharpness. 660 // Where N ranges between, 661 // N = 0.50 (default) 662 // N = 0.33 (sharper) 663 // {x__} = -N/screenWidthInPixels 664 // {_y_} = -N/screenHeightInPixels 665 // {_z_} = N/screenWidthInPixels 666 // {__w} = N/screenHeightInPixels 667 FxaaFloat4 fxaaConsoleRcpFrameOpt, 668 // 669 // Only used on FXAA Console. 670 // Not used on 360, but used on PS3 and PC. 671 // This must be from a constant/uniform. 672 // {x__} = -2.0/screenWidthInPixels 673 // {_y_} = -2.0/screenHeightInPixels 674 // {_z_} = 2.0/screenWidthInPixels 675 // {__w} = 2.0/screenHeightInPixels 676 FxaaFloat4 fxaaConsoleRcpFrameOpt2, 677 // 678 // Only used on FXAA Console. 679 // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. 680 // This must be from a constant/uniform. 681 // {x__} = 8.0/screenWidthInPixels 682 // {_y_} = 8.0/screenHeightInPixels 683 // {_z_} = -4.0/screenWidthInPixels 684 // {__w} = -4.0/screenHeightInPixels 685 FxaaFloat4 fxaaConsole360RcpFrameOpt2, 686 // 687 // Only used on FXAA Quality. 688 // This used to be the FXAA_QUALITY_SUBPIX define. 689 // It is here now to allow easier tuning. 690 // Choose the amount of sub-pixel aliasing removal. 691 // This can effect sharpness. 692 // 1.00 - upper limit (softer) 693 // 0.75 - default amount of filtering 694 // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) 695 // 0.25 - almost off 696 // 0.00 - completely off 697 FxaaFloat fxaaQualitySubpix, 698 // 699 // Only used on FXAA Quality. 700 // This used to be the FXAA_QUALITY_EDGE_THRESHOLD define. 701 // It is here now to allow easier tuning. 702 // The minimum amount of local contrast required to apply algorithm. 703 // 0.333 - too little (faster) 704 // 0.250 - low quality 705 // 0.166 - default 706 // 0.125 - high quality 707 // 0.063 - overkill (slower) 708 FxaaFloat fxaaQualityEdgeThreshold, 709 // 710 // Only used on FXAA Quality. 711 // This used to be the FXAA_QUALITY_EDGE_THRESHOLD_MIN define. 712 // It is here now to allow easier tuning. 713 // Trims the algorithm from processing darks. 714 // 0.0833 - upper limit (default, the start of visible unfiltered edges) 715 // 0.0625 - high quality (faster) 716 // 0.0312 - visible limit (slower) 717 // Special notes when using FXAA_GREEN_AS_LUMA, 718 // Likely want to set this to zero. 719 // As colors that are mostly not-green 720 // will appear very dark in the green channel! 721 // Tune by looking at mostly non-green content, 722 // then start at zero and increase until aliasing is a problem. 723 FxaaFloat fxaaQualityEdgeThresholdMin, 724 // 725 // Only used on FXAA Console. 726 // This used to be the FXAA_CONSOLE_EDGE_SHARPNESS define. 727 // It is here now to allow easier tuning. 728 // This does not effect PS3, as this needs to be compiled in. 729 // Use FXAA_CONSOLE_PS3_EDGE_SHARPNESS for PS3. 730 // Due to the PS3 being ALU bound, 731 // there are only three safe values here: 2 and 4 and 8. 732 // These options use the shaders ability to a free *|/ by 2|4|8. 733 // For all other platforms can be a non-power of two. 734 // 8.0 is sharper (default!!!) 735 // 4.0 is softer 736 // 2.0 is really soft (good only for vector graphics inputs) 737 FxaaFloat fxaaConsoleEdgeSharpness, 738 // 739 // Only used on FXAA Console. 740 // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD define. 741 // It is here now to allow easier tuning. 742 // This does not effect PS3, as this needs to be compiled in. 743 // Use FXAA_CONSOLE_PS3_EDGE_THRESHOLD for PS3. 744 // Due to the PS3 being ALU bound, 745 // there are only two safe values here: 1/4 and 1/8. 746 // These options use the shaders ability to a free *|/ by 2|4|8. 747 // The console setting has a different mapping than the quality setting. 748 // Other platforms can use other values. 749 // 0.125 leaves less aliasing, but is softer (default!!!) 750 // 0.25 leaves more aliasing, and is sharper 751 FxaaFloat fxaaConsoleEdgeThreshold, 752 // 753 // Only used on FXAA Console. 754 // This used to be the FXAA_CONSOLE_EDGE_THRESHOLD_MIN define. 755 // It is here now to allow easier tuning. 756 // Trims the algorithm from processing darks. 757 // The console setting has a different mapping than the quality setting. 758 // This only applies when FXAA_EARLY_EXIT is 1. 759 // This does not apply to PS3, 760 // PS3 was simplified to avoid more shader instructions. 761 // 0.06 - faster but more aliasing in darks 762 // 0.05 - default 763 // 0.04 - slower and less aliasing in darks 764 // Special notes when using FXAA_GREEN_AS_LUMA, 765 // Likely want to set this to zero. 766 // As colors that are mostly not-green 767 // will appear very dark in the green channel! 768 // Tune by looking at mostly non-green content, 769 // then start at zero and increase until aliasing is a problem. 770 FxaaFloat fxaaConsoleEdgeThresholdMin, 771 // 772 // Extra constants for 360 FXAA Console only. 773 // Use zeros or anything else for other platforms. 774 // These must be in physical constant registers and NOT immedates. 775 // Immedates will result in compiler un-optimizing. 776 // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) 777 FxaaFloat4 fxaaConsole360ConstDir 778 ) { 779 /*--------------------------------------------------------------------------*/ 780 FxaaFloat2 posM; 781 posM.x = pos.x; 782 posM.y = pos.y; 783 #if (FXAA_GATHER4_ALPHA == 1) 784 #if (FXAA_DISCARD == 0) 785 FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); 786 #if (FXAA_GREEN_AS_LUMA == 0) 787 #define lumaM rgbyM.w 788 #else 789 #define lumaM rgbyM.y 790 #endif 791 #endif 792 #if (FXAA_GREEN_AS_LUMA == 0) 793 FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); 794 FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); 795 #else 796 FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); 797 FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); 798 #endif 799 #if (FXAA_DISCARD == 1) 800 #define lumaM luma4A.w 801 #endif 802 #define lumaE luma4A.z 803 #define lumaS luma4A.x 804 #define lumaSE luma4A.y 805 #define lumaNW luma4B.w 806 #define lumaN luma4B.z 807 #define lumaW luma4B.x 808 #else 809 FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); 810 #if (FXAA_GREEN_AS_LUMA == 0) 811 #define lumaM rgbyM.w 812 #else 813 #define lumaM rgbyM.y 814 #endif 815 FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); 816 FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); 817 FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); 818 FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); 819 #endif 820 /*--------------------------------------------------------------------------*/ 821 FxaaFloat maxSM = max(lumaS, lumaM); 822 FxaaFloat minSM = min(lumaS, lumaM); 823 FxaaFloat maxESM = max(lumaE, maxSM); 824 FxaaFloat minESM = min(lumaE, minSM); 825 FxaaFloat maxWN = max(lumaN, lumaW); 826 FxaaFloat minWN = min(lumaN, lumaW); 827 FxaaFloat rangeMax = max(maxWN, maxESM); 828 FxaaFloat rangeMin = min(minWN, minESM); 829 FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; 830 FxaaFloat range = rangeMax - rangeMin; 831 FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); 832 FxaaBool earlyExit = range < rangeMaxClamped; 833 /*--------------------------------------------------------------------------*/ 834 if(earlyExit) 835 #if (FXAA_DISCARD == 1) 836 FxaaDiscard; 837 #else 838 return rgbyM; 839 #endif 840 /*--------------------------------------------------------------------------*/ 841 #if (FXAA_GATHER4_ALPHA == 0) 842 FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); 843 FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); 844 FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); 845 FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); 846 #else 847 FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); 848 FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); 849 #endif 850 /*--------------------------------------------------------------------------*/ 851 FxaaFloat lumaNS = lumaN + lumaS; 852 FxaaFloat lumaWE = lumaW + lumaE; 853 FxaaFloat subpixRcpRange = 1.0/range; 854 FxaaFloat subpixNSWE = lumaNS + lumaWE; 855 FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; 856 FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; 857 /*--------------------------------------------------------------------------*/ 858 FxaaFloat lumaNESE = lumaNE + lumaSE; 859 FxaaFloat lumaNWNE = lumaNW + lumaNE; 860 FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; 861 FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; 862 /*--------------------------------------------------------------------------*/ 863 FxaaFloat lumaNWSW = lumaNW + lumaSW; 864 FxaaFloat lumaSWSE = lumaSW + lumaSE; 865 FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); 866 FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); 867 FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; 868 FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; 869 FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; 870 FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; 871 /*--------------------------------------------------------------------------*/ 872 FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; 873 FxaaFloat lengthSign = fxaaQualityRcpFrame.x; 874 FxaaBool horzSpan = edgeHorz >= edgeVert; 875 FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; 876 /*--------------------------------------------------------------------------*/ 877 if(!horzSpan) lumaN = lumaW; 878 if(!horzSpan) lumaS = lumaE; 879 if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; 880 FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; 881 /*--------------------------------------------------------------------------*/ 882 FxaaFloat gradientN = lumaN - lumaM; 883 FxaaFloat gradientS = lumaS - lumaM; 884 FxaaFloat lumaNN = lumaN + lumaM; 885 FxaaFloat lumaSS = lumaS + lumaM; 886 FxaaBool pairN = abs(gradientN) >= abs(gradientS); 887 FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); 888 if(pairN) lengthSign = -lengthSign; 889 FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); 890 /*--------------------------------------------------------------------------*/ 891 FxaaFloat2 posB; 892 posB.x = posM.x; 893 posB.y = posM.y; 894 FxaaFloat2 offNP; 895 offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; 896 offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; 897 if(!horzSpan) posB.x += lengthSign * 0.5; 898 if( horzSpan) posB.y += lengthSign * 0.5; 899 /*--------------------------------------------------------------------------*/ 900 FxaaFloat2 posN; 901 posN.x = posB.x - offNP.x * FXAA_QUALITY_P0; 902 posN.y = posB.y - offNP.y * FXAA_QUALITY_P0; 903 FxaaFloat2 posP; 904 posP.x = posB.x + offNP.x * FXAA_QUALITY_P0; 905 posP.y = posB.y + offNP.y * FXAA_QUALITY_P0; 906 FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; 907 FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); 908 FxaaFloat subpixE = subpixC * subpixC; 909 FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); 910 /*--------------------------------------------------------------------------*/ 911 if(!pairN) lumaNN = lumaSS; 912 FxaaFloat gradientScaled = gradient * 1.0/4.0; 913 FxaaFloat lumaMM = lumaM - lumaNN * 0.5; 914 FxaaFloat subpixF = subpixD * subpixE; 915 FxaaBool lumaMLTZero = lumaMM < 0.0; 916 /*--------------------------------------------------------------------------*/ 917 lumaEndN -= lumaNN * 0.5; 918 lumaEndP -= lumaNN * 0.5; 919 FxaaBool doneN = abs(lumaEndN) >= gradientScaled; 920 FxaaBool doneP = abs(lumaEndP) >= gradientScaled; 921 if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1; 922 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1; 923 FxaaBool doneNP = (!doneN) || (!doneP); 924 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P1; 925 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P1; 926 /*--------------------------------------------------------------------------*/ 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_P2; 935 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P2; 936 doneNP = (!doneN) || (!doneP); 937 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P2; 938 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P2; 939 /*--------------------------------------------------------------------------*/ 940 #if (FXAA_QUALITY_PS > 3) 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_P3; 949 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P3; 950 doneNP = (!doneN) || (!doneP); 951 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P3; 952 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P3; 953 /*--------------------------------------------------------------------------*/ 954 #if (FXAA_QUALITY_PS > 4) 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_P4; 963 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P4; 964 doneNP = (!doneN) || (!doneP); 965 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P4; 966 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P4; 967 /*--------------------------------------------------------------------------*/ 968 #if (FXAA_QUALITY_PS > 5) 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_P5; 977 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P5; 978 doneNP = (!doneN) || (!doneP); 979 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P5; 980 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P5; 981 /*--------------------------------------------------------------------------*/ 982 #if (FXAA_QUALITY_PS > 6) 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_P6; 991 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P6; 992 doneNP = (!doneN) || (!doneP); 993 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P6; 994 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P6; 995 /*--------------------------------------------------------------------------*/ 996 #if (FXAA_QUALITY_PS > 7) 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_P7; 1005 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P7; 1006 doneNP = (!doneN) || (!doneP); 1007 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P7; 1008 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P7; 1009 /*--------------------------------------------------------------------------*/ 1010 #if (FXAA_QUALITY_PS > 8) 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_P8; 1019 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P8; 1020 doneNP = (!doneN) || (!doneP); 1021 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P8; 1022 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P8; 1023 /*--------------------------------------------------------------------------*/ 1024 #if (FXAA_QUALITY_PS > 9) 1025 if(doneNP) { 1026 if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); 1027 if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); 1028 if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; 1029 if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; 1030 doneN = abs(lumaEndN) >= gradientScaled; 1031 doneP = abs(lumaEndP) >= gradientScaled; 1032 if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P9; 1033 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P9; 1034 doneNP = (!doneN) || (!doneP); 1035 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P9; 1036 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P9; 1037 /*--------------------------------------------------------------------------*/ 1038 #if (FXAA_QUALITY_PS > 10) 1039 if(doneNP) { 1040 if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); 1041 if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); 1042 if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; 1043 if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; 1044 doneN = abs(lumaEndN) >= gradientScaled; 1045 doneP = abs(lumaEndP) >= gradientScaled; 1046 if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P10; 1047 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P10; 1048 doneNP = (!doneN) || (!doneP); 1049 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P10; 1050 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P10; 1051 /*--------------------------------------------------------------------------*/ 1052 #if (FXAA_QUALITY_PS > 11) 1053 if(doneNP) { 1054 if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); 1055 if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); 1056 if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; 1057 if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; 1058 doneN = abs(lumaEndN) >= gradientScaled; 1059 doneP = abs(lumaEndP) >= gradientScaled; 1060 if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P11; 1061 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P11; 1062 doneNP = (!doneN) || (!doneP); 1063 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P11; 1064 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P11; 1065 /*--------------------------------------------------------------------------*/ 1066 #if (FXAA_QUALITY_PS > 12) 1067 if(doneNP) { 1068 if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); 1069 if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); 1070 if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; 1071 if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; 1072 doneN = abs(lumaEndN) >= gradientScaled; 1073 doneP = abs(lumaEndP) >= gradientScaled; 1074 if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P12; 1075 if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P12; 1076 doneNP = (!doneN) || (!doneP); 1077 if(!doneP) posP.x += offNP.x * FXAA_QUALITY_P12; 1078 if(!doneP) posP.y += offNP.y * FXAA_QUALITY_P12; 1079 /*--------------------------------------------------------------------------*/ 1080 } 1081 #endif 1082 /*--------------------------------------------------------------------------*/ 1083 } 1084 #endif 1085 /*--------------------------------------------------------------------------*/ 1086 } 1087 #endif 1088 /*--------------------------------------------------------------------------*/ 1089 } 1090 #endif 1091 /*--------------------------------------------------------------------------*/ 1092 } 1093 #endif 1094 /*--------------------------------------------------------------------------*/ 1095 } 1096 #endif 1097 /*--------------------------------------------------------------------------*/ 1098 } 1099 #endif 1100 /*--------------------------------------------------------------------------*/ 1101 } 1102 #endif 1103 /*--------------------------------------------------------------------------*/ 1104 } 1105 #endif 1106 /*--------------------------------------------------------------------------*/ 1107 } 1108 #endif 1109 /*--------------------------------------------------------------------------*/ 1110 } 1111 /*--------------------------------------------------------------------------*/ 1112 FxaaFloat dstN = posM.x - posN.x; 1113 FxaaFloat dstP = posP.x - posM.x; 1114 if(!horzSpan) dstN = posM.y - posN.y; 1115 if(!horzSpan) dstP = posP.y - posM.y; 1116 /*--------------------------------------------------------------------------*/ 1117 FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; 1118 FxaaFloat spanLength = (dstP + dstN); 1119 FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; 1120 FxaaFloat spanLengthRcp = 1.0/spanLength; 1121 /*--------------------------------------------------------------------------*/ 1122 FxaaBool directionN = dstN < dstP; 1123 FxaaFloat dst = min(dstN, dstP); 1124 FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; 1125 FxaaFloat subpixG = subpixF * subpixF; 1126 FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; 1127 FxaaFloat subpixH = subpixG * fxaaQualitySubpix; 1128 /*--------------------------------------------------------------------------*/ 1129 FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; 1130 FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); 1131 if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; 1132 if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; 1133 #if (FXAA_DISCARD == 1) 1134 return FxaaTexTop(tex, posM); 1135 #else 1136 return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); 1137 #endif 1138 } 1139 /*==========================================================================*/ 1140 #endif 1141 1142 vec4 mainImage(vec2 fragCoord) 1143 { 1144 vec2 rcpFrame = 1./invResolution_data.xy; 1145 vec2 uv2 = fragCoord.xy / invResolution_data.xy; 1146 1147 float fxaaQualitySubpix = 0.75; // [0..1], default 0.75 1148 float fxaaQualityEdgeThreshold = 0.166; // [0.125..0.33], default 0.166 1149 float fxaaQualityEdgeThresholdMin = 0.02;//0.0625; // ? 1150 vec4 dummy4 = vec4(0.0,0.0,0.0,0.0); 1151 float dummy1 = 0.0; 1152 1153 vec4 col = FxaaPixelShader(uv2, dummy4, 1154 inputImage, inputImage, inputImage, 1155 rcpFrame, dummy4, dummy4, dummy4, 1156 fxaaQualitySubpix, fxaaQualityEdgeThreshold, 1157 fxaaQualityEdgeThresholdMin, 1158 dummy1, dummy1, dummy1, dummy4); 1159 1160 vec4 fragColor = vec4( col.xyz, 1. ); 1161 1162 return fragColor; 1163 } 1164 1165 void main() 1166 { 1167 ivec2 loc = ivec2(gl_GlobalInvocationID.x * 4, gl_GlobalInvocationID.y * 4); 1168 for(int i = 0; i < 4; i++) 1169 { 1170 for(int j = 0; j < 4; j++) 1171 { 1172 ivec2 texelCoord = ivec2(loc.x + i, loc.y + j); 1173 vec4 outColor = mainImage(texelCoord + vec2(0.5)); 1174 imageStore(imgOutput, texelCoord, outColor); 1175 } 1176 } 1177 }