Browse Source

Rename EdgeFilter shader to FXAA2. Rename FXAA shader to FXAA3. Clean up FXAA3 GLSL code and port to HLSL.

Lasse Öörni 11 years ago
parent
commit
f2e6e86a1d

+ 4 - 4
Bin/CoreData/Shaders/GLSL/EdgeFilter.glsl → Bin/CoreData/Shaders/GLSL/FXAA2.glsl

@@ -14,7 +14,7 @@
 varying vec2 vScreenPos;
 varying vec2 vScreenPos;
 
 
 #ifdef COMPILEPS
 #ifdef COMPILEPS
-uniform vec3 cEdgeFilterParams;
+uniform vec3 cFXAAParams;
 #endif
 #endif
 
 
 void VS()
 void VS()
@@ -32,7 +32,7 @@ void PS()
     float FXAA_REDUCE_MUL = 1.0/8.0;
     float FXAA_REDUCE_MUL = 1.0/8.0;
     float FXAA_REDUCE_MIN = 1.0/128.0;
     float FXAA_REDUCE_MIN = 1.0/128.0;
 
 
-    vec2 posOffset = cGBufferInvSize.xy * cEdgeFilterParams.x;
+    vec2 posOffset = cGBufferInvSize.xy * cFXAAParams.x;
 
 
     vec3 rgbNW = texture2D(sDiffMap, vScreenPos + vec2(-posOffset.x, -posOffset.y)).rgb;
     vec3 rgbNW = texture2D(sDiffMap, vScreenPos + vec2(-posOffset.x, -posOffset.y)).rgb;
     vec3 rgbNE = texture2D(sDiffMap, vScreenPos + vec2(posOffset.x, -posOffset.y)).rgb;
     vec3 rgbNE = texture2D(sDiffMap, vScreenPos + vec2(posOffset.x, -posOffset.y)).rgb;
@@ -50,7 +50,7 @@ void PS()
     float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
     float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
     float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
     float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
 
 
-    if (((lumaMax - lumaMin) / lumaMin) >= cEdgeFilterParams.y)
+    if (((lumaMax - lumaMin) / lumaMin) >= cFXAAParams.y)
     {
     {
         vec2 dir;
         vec2 dir;
         dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
         dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
@@ -64,7 +64,7 @@ void PS()
               max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
               max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
               dir * rcpDirMin)) * cGBufferInvSize.xy;
               dir * rcpDirMin)) * cGBufferInvSize.xy;
 
 
-        dir *= cEdgeFilterParams.z;
+        dir *= cFXAAParams.z;
 
 
         vec3 rgbA = (1.0/2.0) * (
         vec3 rgbA = (1.0/2.0) * (
             texture2D(sDiffMap, vScreenPos + dir * (1.0/3.0 - 0.5)).xyz +
             texture2D(sDiffMap, vScreenPos + dir * (1.0/3.0 - 0.5)).xyz +

+ 23 - 113
Bin/CoreData/Shaders/GLSL/FXAA.glsl → Bin/CoreData/Shaders/GLSL/FXAA3.glsl

@@ -56,56 +56,9 @@ varying vec2 vScreenPos;
 //                      Shader Requirements
 //                      Shader Requirements
 //
 //
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
-//define FXAA_GLSL_130 if GLSL version is >= 130
 
 
-//#define FXAA_GLSL_130
-
-
-/*--------------------------------------------------------------------------*/
-//Messing with these extensions seems dangerous...
-
-//#extension GL_EXT_gpu_shader4 : enable
-//#extension GL_NV_gpu_shader5  : enable
-//#extension GL_ARB_gpu_shader5 : enable
-
-/*==========================================================================*/
-
-#ifndef FXAA_FAST_PIXEL_OFFSET
-    //
-    // Used for GLSL 120 only.
-    //
-    // 1 = GL API supports fast pixel offsets
-    // 0 = do not use fast pixel offsets
-    //
-    #ifdef GL_EXT_gpu_shader4
-        #define FXAA_FAST_PIXEL_OFFSET 1
-    #endif
-    #ifdef GL_NV_gpu_shader5
-        #define FXAA_FAST_PIXEL_OFFSET 1
-    #endif
-    #ifdef GL_ARB_gpu_shader5
-        #define FXAA_FAST_PIXEL_OFFSET 1
-    #endif
-    #ifndef FXAA_FAST_PIXEL_OFFSET
-        #define FXAA_FAST_PIXEL_OFFSET 0
-    #endif
-#endif
-/*--------------------------------------------------------------------------*/
-#ifndef FXAA_GATHER4
-    //
-    // 1 = API supports gather4 on alpha channel.
-    // 0 = API does not support gather4 on alpha channel.
-    //
-    #ifdef GL_ARB_gpu_shader5
-        #define FXAA_GATHER4 1
-    #endif
-    #ifdef GL_NV_gpu_shader5
-        #define FXAA_GATHER4 1
-    #endif
-    #ifndef FXAA_GATHER4
-        #define FXAA_GATHER4 0
-    #endif
-#endif
+#define FXAA_FAST_PIXEL_OFFSET 0
+#define FXAA_GATHER4 0
 
 
 /*============================================================================
 /*============================================================================
                         FXAA QUALITY - TUNING KNOBS
                         FXAA QUALITY - TUNING KNOBS
@@ -118,7 +71,7 @@ NOTE the other tuning knobs are now in the shader function inputs!
     // This needs to be compiled into the shader as it effects code.
     // This needs to be compiled into the shader as it effects code.
     // Best option to include multiple presets is to 
     // Best option to include multiple presets is to 
     // in each shader define the preset, then include this file.
     // in each shader define the preset, then include this file.
-    // 
+    //
     // OPTIONS
     // OPTIONS
     // -----------------------------------------------------------------------
     // -----------------------------------------------------------------------
     // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
     // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
@@ -358,55 +311,12 @@ vec4 MakeRGBA(vec3 rgb)
 {
 {
     return vec4(rgb, CalcLuma(rgb));
     return vec4(rgb, CalcLuma(rgb));
 }
 }
-/*--------------------------------------------------------------------------*/
-#if (FXAA_GATHER4 == 1)
-  vec4 FxaaTex4(sampler2D t, vec2 p)
-  {
-      vec4 R = textureGather(t, p, 0);
-      vec4 G = textureGather(t, p, 1);
-      vec4 B = textureGather(t, p, 2);
-      
-      float one = CalcLuma(vec3(R.r, G.r, B.r));
-      float two = CalcLuma(vec3(R.g, G.g, B.g));
-      float three = CalcLuma(vec3 (R.b, G.b, B.b));
-      float four = CalcLuma(vec3 (R.a, G.a, B.a));
-
-      return vec4(one, two, three, four);
-  }
-
-  vec4 FxaaTexOff4(sampler2D t, vec2 p, ivec2 o)
-  {   
-      vec4 R = textureGatherOffset(t, p, o, 0);
-      vec4 G = textureGatherOffset(t, p, o, 1);
-      vec4 B = textureGatherOffset(t, p, o, 2);
-      
-      float one = CalcLuma(vec3(R.r, G.r, B.r));
-      float two = CalcLuma(vec3(R.g, G.g, B.g));
-      float three = CalcLuma(vec3 (R.b, G.b, B.b));
-      float four = CalcLuma(vec3 (R.a, G.a, B.a));
-
-      return vec4(one, two, three, four);
-  }
-#endif
-/*--------------------------------------------------------------------------*/
-#ifndef FXAA_GLSL_130
-    // Requires,
-    //  #version 120
-    // And at least,
-    //  #extension GL_EXT_gpu_shader4 : enable
-    //  (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
-    #define FxaaTexTop(t, p) MakeRGBA(texture2DLod(t, p, 0.0).rgb)
-    #if (FXAA_FAST_PIXEL_OFFSET == 1)
-        #define FxaaTexOff(t, p, o, r) MakeRGBA(texture2DLodOffset(t, p, 0.0, o).rgb)
-    #else
-        #define FxaaTexOff(t, p, o, r) MakeRGBA(texture2DLod(t, p + (o * r), 0.0).rgb)
-    #endif
-#endif
-/*--------------------------------------------------------------------------*/
-#ifdef FXAA_GLSL_130
-    // Requires "#version 130" or better
-    #define FxaaTexTop(t, p) MakeRGBA(textureLod(t, p, 0.0).rgb)
-    #define FxaaTexOff(t, p, o, r) MakeRGBA(textureLodOffset(t, p, 0.0, o).rgb)
+
+#define FxaaTexTop(t, p) MakeRGBA(texture2DLod(t, p, 0.0).rgb)
+#if (FXAA_FAST_PIXEL_OFFSET == 1)
+    #define FxaaTexOff(t, p, o, r) MakeRGBA(texture2DLodOffset(t, p, 0.0, o).rgb)
+#else
+    #define FxaaTexOff(t, p, o, r) MakeRGBA(texture2DLod(t, p + (o * r), 0.0).rgb)
 #endif
 #endif
 
 
 /*============================================================================
 /*============================================================================
@@ -478,7 +388,7 @@ vec4 FxaaPixelShader(
     #if (FXAA_GATHER4 == 1)
     #if (FXAA_GATHER4 == 1)
         vec4 rgbyM = FxaaTexTop(tex, posM);
         vec4 rgbyM = FxaaTexTop(tex, posM);
         vec4 luma4A = FxaaTex4(tex, posM);
         vec4 luma4A = FxaaTex4(tex, posM);
-        vec4 luma4B = FxaaTexOff4(tex, posM, ivec2(-1, -1));
+        vec4 luma4B = FxaaTexOff4(tex, posM, vec2(-1, -1));
         #define lumaM rgbyM.w
         #define lumaM rgbyM.w
         #define lumaE luma4A.z
         #define lumaE luma4A.z
         #define lumaS luma4A.x
         #define lumaS luma4A.x
@@ -489,10 +399,10 @@ vec4 FxaaPixelShader(
     #else
     #else
         vec4 rgbyM = FxaaTexTop(tex, posM);
         vec4 rgbyM = FxaaTexTop(tex, posM);
         #define lumaM rgbyM.y
         #define lumaM rgbyM.y
-        float lumaS = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 0, 1), fxaaQualityRcpFrame.xy));
-        float lumaE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1, 0), fxaaQualityRcpFrame.xy));
-        float lumaN = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 0,-1), fxaaQualityRcpFrame.xy));
-        float lumaW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1, 0), fxaaQualityRcpFrame.xy));
+        float lumaS = FxaaLuma(FxaaTexOff(tex, posM, vec2( 0, 1), fxaaQualityRcpFrame.xy));
+        float lumaE = FxaaLuma(FxaaTexOff(tex, posM, vec2( 1, 0), fxaaQualityRcpFrame.xy));
+        float lumaN = FxaaLuma(FxaaTexOff(tex, posM, vec2( 0,-1), fxaaQualityRcpFrame.xy));
+        float lumaW = FxaaLuma(FxaaTexOff(tex, posM, vec2(-1, 0), fxaaQualityRcpFrame.xy));
     #endif
     #endif
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
     float maxSM = max(lumaS, lumaM);
     float maxSM = max(lumaS, lumaM);
@@ -512,13 +422,13 @@ vec4 FxaaPixelShader(
         return FxaaTexTop(tex, pos);
         return FxaaTexTop(tex, pos);
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
     #if (FXAA_GATHER4 == 0)
     #if (FXAA_GATHER4 == 0)
-        float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1,-1), fxaaQualityRcpFrame.xy));
-        float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1, 1), fxaaQualityRcpFrame.xy));
-        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, ivec2( 1,-1), fxaaQualityRcpFrame.xy));
-        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1, 1), fxaaQualityRcpFrame.xy));
+        float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, vec2(-1,-1), fxaaQualityRcpFrame.xy));
+        float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, vec2( 1, 1), fxaaQualityRcpFrame.xy));
+        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, vec2( 1,-1), fxaaQualityRcpFrame.xy));
+        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, vec2(-1, 1), fxaaQualityRcpFrame.xy));
     #else
     #else
-        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, ivec2(1, -1), fxaaQualityRcpFrame.xy));
-        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, ivec2(-1, 1), fxaaQualityRcpFrame.xy));
+        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, vec2(1, -1), fxaaQualityRcpFrame.xy));
+        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, vec2(-1, 1), fxaaQualityRcpFrame.xy));
     #endif
     #endif
 /*--------------------------------------------------------------------------*/
 /*--------------------------------------------------------------------------*/
     float lumaNS = lumaN + lumaS;
     float lumaNS = lumaN + lumaS;
@@ -829,9 +739,9 @@ void PS()
         vScreenPos,							// vec2 pos,
         vScreenPos,							// vec2 pos,
         sDiffMap,							// sampler2D tex,
         sDiffMap,							// sampler2D tex,
         rcpFrame,							// vec2 fxaaQualityRcpFrame,
         rcpFrame,							// vec2 fxaaQualityRcpFrame,
-        0.75f,									// float fxaaQualitySubpix,
-        0.166f,									// float fxaaQualityEdgeThreshold,
-        0.0833f								// float fxaaQualityEdgeThresholdMin
+        0.75,								// float fxaaQualitySubpix,
+        0.166,								// float fxaaQualityEdgeThreshold,
+        0.0833								// float fxaaQualityEdgeThresholdMin
     ).rgb, 1.0);
     ).rgb, 1.0);
 }
 }
 
 

+ 4 - 4
Bin/CoreData/Shaders/HLSL/EdgeFilter.hlsl → Bin/CoreData/Shaders/HLSL/FXAA2.hlsl

@@ -11,7 +11,7 @@
 #include "Transform.hlsl"
 #include "Transform.hlsl"
 #include "ScreenPos.hlsl"
 #include "ScreenPos.hlsl"
 
 
-uniform float4 cEdgeFilterParams;
+uniform float4 cFXAAParams;
 
 
 void VS(float4 iPos : POSITION,
 void VS(float4 iPos : POSITION,
     out float4 oPos : POSITION,
     out float4 oPos : POSITION,
@@ -31,7 +31,7 @@ void PS(float2 iScreenPos : TEXCOORD0,
     float FXAA_REDUCE_MUL = 1.0/8.0;
     float FXAA_REDUCE_MUL = 1.0/8.0;
     float FXAA_REDUCE_MIN = 1.0/128.0;
     float FXAA_REDUCE_MIN = 1.0/128.0;
 
 
-    float2 posOffset = cGBufferInvSize.xy * cEdgeFilterParams.x;
+    float2 posOffset = cGBufferInvSize.xy * cFXAAParams.x;
 
 
     float3 rgbNW = Sample(sDiffMap, iScreenPos + float2(-posOffset.x, -posOffset.y)).rgb;
     float3 rgbNW = Sample(sDiffMap, iScreenPos + float2(-posOffset.x, -posOffset.y)).rgb;
     float3 rgbNE = Sample(sDiffMap, iScreenPos + float2(posOffset.x, -posOffset.y)).rgb;
     float3 rgbNE = Sample(sDiffMap, iScreenPos + float2(posOffset.x, -posOffset.y)).rgb;
@@ -49,7 +49,7 @@ void PS(float2 iScreenPos : TEXCOORD0,
     float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
     float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
     float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
     float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
 
 
-    if (((lumaMax - lumaMin) / lumaMin) >= cEdgeFilterParams.y)
+    if (((lumaMax - lumaMin) / lumaMin) >= cFXAAParams.y)
     {
     {
         float2 dir;
         float2 dir;
         dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
         dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
@@ -63,7 +63,7 @@ void PS(float2 iScreenPos : TEXCOORD0,
               max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
               max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
               dir * rcpDirMin)) * cGBufferInvSize.xy;
               dir * rcpDirMin)) * cGBufferInvSize.xy;
     
     
-        dir *= cEdgeFilterParams.z;
+        dir *= cFXAAParams.z;
     
     
         float3 rgbA = (1.0/2.0) * (
         float3 rgbA = (1.0/2.0) * (
             Sample(sDiffMap, iScreenPos + dir * (1.0/3.0 - 0.5)).xyz +
             Sample(sDiffMap, iScreenPos + dir * (1.0/3.0 - 0.5)).xyz +

+ 743 - 0
Bin/CoreData/Shaders/HLSL/FXAA3.hlsl

@@ -0,0 +1,743 @@
+//----------------------------------------------------------------------------------
+//
+// Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//  * Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+//  * Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//  * Neither the name of NVIDIA CORPORATION nor the names of its
+//    contributors may be used to endorse or promote products derived
+//    from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//----------------------------------------------------------------------------------
+/*============================================================================
+
+
+                    NVIDIA FXAA 3.11 by TIMOTHY LOTTES
+
+------------------------------------------------------------------------------
+
+                           Modified for Urho3D
+
+============================================================================*/
+
+/*==========================================================================*/
+//
+//                      Urho3D specific preparations
+//
+/*--------------------------------------------------------------------------*/
+
+#include "Uniforms.hlsl"
+#include "Samplers.hlsl"
+#include "Transform.hlsl"
+#include "ScreenPos.hlsl"
+
+/*==========================================================================*/
+//
+//                      Shader Requirements
+//
+/*--------------------------------------------------------------------------*/
+
+#define FXAA_GATHER4 0
+
+/*============================================================================
+                        FXAA QUALITY - TUNING KNOBS
+------------------------------------------------------------------------------
+NOTE the other tuning knobs are now in the shader function inputs!
+============================================================================*/
+#ifndef FXAA_QUALITY__PRESET
+    //
+    // Choose the quality preset.
+    // This needs to be compiled into the shader as it effects code.
+    // Best option to include multiple presets is to 
+    // in each shader define the preset, then include this file.
+    // 
+    // OPTIONS
+    // -----------------------------------------------------------------------
+    // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
+    // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
+    // 39       - no dither, very expensive 
+    //
+    // NOTES
+    // -----------------------------------------------------------------------
+    // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
+    // 13 = about same speed as FXAA 3.9 and better than 12
+    // 23 = closest to FXAA 3.9 visually and performance wise
+    //  _ = the lowest digit is directly related to performance
+    // _  = the highest digit is directly related to style
+    // 
+    #define FXAA_QUALITY__PRESET 12
+#endif
+
+
+/*============================================================================
+
+                           FXAA QUALITY - PRESETS
+
+============================================================================*/
+
+/*============================================================================
+                     FXAA QUALITY - MEDIUM DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 10)
+    #define FXAA_QUALITY__PS 3
+    #define FXAA_QUALITY__P0 1.5
+    #define FXAA_QUALITY__P1 3.0
+    #define FXAA_QUALITY__P2 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 11)
+    #define FXAA_QUALITY__PS 4
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 3.0
+    #define FXAA_QUALITY__P3 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 12)
+    #define FXAA_QUALITY__PS 5
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 4.0
+    #define FXAA_QUALITY__P4 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 13)
+    #define FXAA_QUALITY__PS 6
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 4.0
+    #define FXAA_QUALITY__P5 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 14)
+    #define FXAA_QUALITY__PS 7
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 4.0
+    #define FXAA_QUALITY__P6 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 15)
+    #define FXAA_QUALITY__PS 8
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 4.0
+    #define FXAA_QUALITY__P7 12.0
+#endif
+
+/*============================================================================
+                     FXAA QUALITY - LOW DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 20)
+    #define FXAA_QUALITY__PS 3
+    #define FXAA_QUALITY__P0 1.5
+    #define FXAA_QUALITY__P1 2.0
+    #define FXAA_QUALITY__P2 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 21)
+    #define FXAA_QUALITY__PS 4
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 22)
+    #define FXAA_QUALITY__PS 5
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 23)
+    #define FXAA_QUALITY__PS 6
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 24)
+    #define FXAA_QUALITY__PS 7
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 3.0
+    #define FXAA_QUALITY__P6 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 25)
+    #define FXAA_QUALITY__PS 8
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 4.0
+    #define FXAA_QUALITY__P7 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 26)
+    #define FXAA_QUALITY__PS 9
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 4.0
+    #define FXAA_QUALITY__P8 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 27)
+    #define FXAA_QUALITY__PS 10
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 4.0
+    #define FXAA_QUALITY__P9 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 28)
+    #define FXAA_QUALITY__PS 11
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 4.0
+    #define FXAA_QUALITY__P10 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 29)
+    #define FXAA_QUALITY__PS 12
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.5
+    #define FXAA_QUALITY__P2 2.0
+    #define FXAA_QUALITY__P3 2.0
+    #define FXAA_QUALITY__P4 2.0
+    #define FXAA_QUALITY__P5 2.0
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 2.0
+    #define FXAA_QUALITY__P10 4.0
+    #define FXAA_QUALITY__P11 8.0
+#endif
+
+/*============================================================================
+                     FXAA QUALITY - EXTREME QUALITY
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 39)
+    #define FXAA_QUALITY__PS 12
+    #define FXAA_QUALITY__P0 1.0
+    #define FXAA_QUALITY__P1 1.0
+    #define FXAA_QUALITY__P2 1.0
+    #define FXAA_QUALITY__P3 1.0
+    #define FXAA_QUALITY__P4 1.0
+    #define FXAA_QUALITY__P5 1.5
+    #define FXAA_QUALITY__P6 2.0
+    #define FXAA_QUALITY__P7 2.0
+    #define FXAA_QUALITY__P8 2.0
+    #define FXAA_QUALITY__P9 2.0
+    #define FXAA_QUALITY__P10 4.0
+    #define FXAA_QUALITY__P11 8.0
+#endif
+
+/*============================================================================
+
+                            Support Functions
+
+============================================================================*/
+
+float FxaaLuma(float4 rgba) { return rgba.w; }
+/*--------------------------------------------------------------------------*/
+float CalcLuma(float3 rgb)
+{
+    float3 luma = float3(0.299, 0.587, 0.114);
+    return dot(rgb, luma);
+}
+/*--------------------------------------------------------------------------*/
+float4 MakeRGBA(float3 rgb) 
+{
+    return float4(rgb, CalcLuma(rgb));
+}
+
+#define FxaaTexTop(t, p) MakeRGBA(tex2Dlod(t, float4(p, 0.0, 0.0)).rgb)
+#define FxaaTexOff(t, p, o, r) MakeRGBA(tex2Dlod(t, float4(p + (o * r), 0, 0)).rgb)
+
+/*============================================================================
+
+                             FXAA3 QUALITY - PC
+
+============================================================================*/
+float4 FxaaPixelShader(
+    //
+    // Use noperspective interpolation here (turn off perspective interpolation).
+    // {xy} = center of pixel
+    float2 pos,
+    //
+    // Input color texture.
+    // {rgb_} = color in linear or perceptual color space
+    // if (FXAA_GREEN_AS_LUMA == 0)
+    //     {___a} = luma in perceptual color space (not linear)
+    sampler2D tex,
+    //
+    // Only used on FXAA Quality.
+    // This must be from a constant/uniform.
+    // {x_} = 1.0/screenWidthInPixels
+    // {_y} = 1.0/screenHeightInPixels
+    float2 fxaaQualityRcpFrame,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__SUBPIX define.
+    // It is here now to allow easier tuning.
+    // Choose the amount of sub-pixel aliasing removal.
+    // This can effect sharpness.
+    //   1.00 - upper limit (softer)
+    //   0.75 - default amount of filtering
+    //   0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+    //   0.25 - almost off
+    //   0.00 - completely off
+    float fxaaQualitySubpix,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
+    // It is here now to allow easier tuning.
+    // The minimum amount of local contrast required to apply algorithm.
+    //   0.333 - too little (faster)
+    //   0.250 - low quality
+    //   0.166 - default
+    //   0.125 - high quality 
+    //   0.063 - overkill (slower)
+    float fxaaQualityEdgeThreshold,
+    //
+    // Only used on FXAA Quality.
+    // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
+    // It is here now to allow easier tuning.
+    // Trims the algorithm from processing darks.
+    //   0.0833 - upper limit (default, the start of visible unfiltered edges)
+    //   0.0625 - high quality (faster)
+    //   0.0312 - visible limit (slower)
+    // Special notes when using FXAA_GREEN_AS_LUMA,
+    //   Likely want to set this to zero.
+    //   As colors that are mostly not-green
+    //   will appear very dark in the green channel!
+    //   Tune by looking at mostly non-green content,
+    //   then start at zero and increase until aliasing is a problem.
+    float fxaaQualityEdgeThresholdMin
+) {
+/*--------------------------------------------------------------------------*/
+    float2 posM;
+    posM.x = pos.x;
+    posM.y = pos.y;
+    
+    #if (FXAA_GATHER4 == 1)
+        float4 rgbyM = FxaaTexTop(tex, posM);
+        float4 luma4A = FxaaTex4(tex, posM);
+        float4 luma4B = FxaaTexOff4(tex, posM, float2(-1, -1));
+        #define lumaM rgbyM.w
+        #define lumaE luma4A.z
+        #define lumaS luma4A.x
+        #define lumaSE luma4A.y
+        #define lumaNW luma4B.w
+        #define lumaN luma4B.z
+        #define lumaW luma4B.x
+    #else
+        float4 rgbyM = FxaaTexTop(tex, posM);
+        #define lumaM rgbyM.y
+        float lumaS = FxaaLuma(FxaaTexOff(tex, posM, float2( 0, 1), fxaaQualityRcpFrame.xy));
+        float lumaE = FxaaLuma(FxaaTexOff(tex, posM, float2( 1, 0), fxaaQualityRcpFrame.xy));
+        float lumaN = FxaaLuma(FxaaTexOff(tex, posM, float2( 0,-1), fxaaQualityRcpFrame.xy));
+        float lumaW = FxaaLuma(FxaaTexOff(tex, posM, float2(-1, 0), fxaaQualityRcpFrame.xy));
+    #endif
+/*--------------------------------------------------------------------------*/
+    float maxSM = max(lumaS, lumaM);
+    float minSM = min(lumaS, lumaM);
+    float maxESM = max(lumaE, maxSM);
+    float minESM = min(lumaE, minSM);
+    float maxWN = max(lumaN, lumaW);
+    float minWN = min(lumaN, lumaW);
+    float rangeMax = max(maxWN, maxESM);
+    float rangeMin = min(minWN, minESM);
+    float rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
+    float range = rangeMax - rangeMin;
+    float rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
+    bool earlyExit = range < rangeMaxClamped;
+/*--------------------------------------------------------------------------*/
+    if(earlyExit)
+        return FxaaTexTop(tex, pos);
+/*--------------------------------------------------------------------------*/
+    #if (FXAA_GATHER4 == 0)
+        float lumaNW = FxaaLuma(FxaaTexOff(tex, posM, float2(-1,-1), fxaaQualityRcpFrame.xy));
+        float lumaSE = FxaaLuma(FxaaTexOff(tex, posM, float2( 1, 1), fxaaQualityRcpFrame.xy));
+        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, float2( 1,-1), fxaaQualityRcpFrame.xy));
+        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, float2(-1, 1), fxaaQualityRcpFrame.xy));
+    #else
+        float lumaNE = FxaaLuma(FxaaTexOff(tex, posM, float2(1, -1), fxaaQualityRcpFrame.xy));
+        float lumaSW = FxaaLuma(FxaaTexOff(tex, posM, float2(-1, 1), fxaaQualityRcpFrame.xy));
+    #endif
+/*--------------------------------------------------------------------------*/
+    float lumaNS = lumaN + lumaS;
+    float lumaWE = lumaW + lumaE;
+    float subpixRcpRange = 1.0/range;
+    float subpixNSWE = lumaNS + lumaWE;
+    float edgeHorz1 = (-2.0 * lumaM) + lumaNS;
+    float edgeVert1 = (-2.0 * lumaM) + lumaWE;
+/*--------------------------------------------------------------------------*/
+    float lumaNESE = lumaNE + lumaSE;
+    float lumaNWNE = lumaNW + lumaNE;
+    float edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
+    float edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
+/*--------------------------------------------------------------------------*/
+    float lumaNWSW = lumaNW + lumaSW;
+    float lumaSWSE = lumaSW + lumaSE;
+    float edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
+    float edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
+    float edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
+    float edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
+    float edgeHorz = abs(edgeHorz3) + edgeHorz4;
+    float edgeVert = abs(edgeVert3) + edgeVert4;
+/*--------------------------------------------------------------------------*/
+    float subpixNWSWNESE = lumaNWSW + lumaNESE;
+    float lengthSign = fxaaQualityRcpFrame.x;
+    bool horzSpan = edgeHorz >= edgeVert;
+    float subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
+/*--------------------------------------------------------------------------*/
+    if(!horzSpan) lumaN = lumaW;
+    if(!horzSpan) lumaS = lumaE;
+    if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
+    float subpixB = (subpixA * (1.0/12.0)) - lumaM;
+/*--------------------------------------------------------------------------*/
+    float gradientN = lumaN - lumaM;
+    float gradientS = lumaS - lumaM;
+    float lumaNN = lumaN + lumaM;
+    float lumaSS = lumaS + lumaM;
+    bool pairN = abs(gradientN) >= abs(gradientS);
+    float gradient = max(abs(gradientN), abs(gradientS));
+    if(pairN) lengthSign = -lengthSign;
+    float subpixC = clamp((abs(subpixB) * subpixRcpRange), 0.0, 1.0);
+/*--------------------------------------------------------------------------*/
+    float2 posB;
+    posB.x = posM.x;
+    posB.y = posM.y;
+    float2 offNP;
+    offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
+    offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
+    if(!horzSpan) posB.x += lengthSign * 0.5;
+    if( horzSpan) posB.y += lengthSign * 0.5;
+/*--------------------------------------------------------------------------*/
+    float2 posN;
+    posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
+    posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
+    float2 posP;
+    posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
+    posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
+    float subpixD = ((-2.0)*subpixC) + 3.0;
+    float lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
+    float subpixE = subpixC * subpixC;
+    float lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
+/*--------------------------------------------------------------------------*/
+    if(!pairN) lumaNN = lumaSS;
+    float gradientScaled = gradient * 1.0/4.0;
+    float lumaMM = lumaM - lumaNN * 0.5;
+    float subpixF = subpixD * subpixE;
+    bool lumaMLTZero = lumaMM < 0.0;
+/*--------------------------------------------------------------------------*/
+    lumaEndN -= lumaNN * 0.5;
+    lumaEndP -= lumaNN * 0.5;
+    bool doneN = abs(lumaEndN) >= gradientScaled;
+    bool doneP = abs(lumaEndP) >= gradientScaled;
+    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
+    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
+    bool doneNP = (!doneN) || (!doneP);
+    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
+    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
+/*--------------------------------------------------------------------------*/
+    if(doneNP) {
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+        doneN = abs(lumaEndN) >= gradientScaled;
+        doneP = abs(lumaEndP) >= gradientScaled;
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
+        doneNP = (!doneN) || (!doneP);
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
+/*--------------------------------------------------------------------------*/
+        #if (FXAA_QUALITY__PS > 3)
+        if(doneNP) {
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+            doneN = abs(lumaEndN) >= gradientScaled;
+            doneP = abs(lumaEndP) >= gradientScaled;
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
+            doneNP = (!doneN) || (!doneP);
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
+/*--------------------------------------------------------------------------*/
+            #if (FXAA_QUALITY__PS > 4)
+            if(doneNP) {
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                doneN = abs(lumaEndN) >= gradientScaled;
+                doneP = abs(lumaEndP) >= gradientScaled;
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
+                doneNP = (!doneN) || (!doneP);
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
+/*--------------------------------------------------------------------------*/
+                #if (FXAA_QUALITY__PS > 5)
+                if(doneNP) {
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                    doneN = abs(lumaEndN) >= gradientScaled;
+                    doneP = abs(lumaEndP) >= gradientScaled;
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
+                    doneNP = (!doneN) || (!doneP);
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
+/*--------------------------------------------------------------------------*/
+                    #if (FXAA_QUALITY__PS > 6)
+                    if(doneNP) {
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                        doneN = abs(lumaEndN) >= gradientScaled;
+                        doneP = abs(lumaEndP) >= gradientScaled;
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
+                        doneNP = (!doneN) || (!doneP);
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
+/*--------------------------------------------------------------------------*/
+                        #if (FXAA_QUALITY__PS > 7)
+                        if(doneNP) {
+                            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                            doneN = abs(lumaEndN) >= gradientScaled;
+                            doneP = abs(lumaEndP) >= gradientScaled;
+                            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
+                            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
+                            doneNP = (!doneN) || (!doneP);
+                            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
+                            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
+/*--------------------------------------------------------------------------*/
+    #if (FXAA_QUALITY__PS > 8)
+    if(doneNP) {
+        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+        doneN = abs(lumaEndN) >= gradientScaled;
+        doneP = abs(lumaEndP) >= gradientScaled;
+        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
+        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
+        doneNP = (!doneN) || (!doneP);
+        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
+        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
+/*--------------------------------------------------------------------------*/
+        #if (FXAA_QUALITY__PS > 9)
+        if(doneNP) {
+            if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+            if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+            if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+            if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+            doneN = abs(lumaEndN) >= gradientScaled;
+            doneP = abs(lumaEndP) >= gradientScaled;
+            if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
+            if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
+            doneNP = (!doneN) || (!doneP);
+            if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
+            if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
+/*--------------------------------------------------------------------------*/
+            #if (FXAA_QUALITY__PS > 10)
+            if(doneNP) {
+                if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                doneN = abs(lumaEndN) >= gradientScaled;
+                doneP = abs(lumaEndP) >= gradientScaled;
+                if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
+                if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
+                doneNP = (!doneN) || (!doneP);
+                if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
+                if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
+/*--------------------------------------------------------------------------*/
+                #if (FXAA_QUALITY__PS > 11)
+                if(doneNP) {
+                    if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                    if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                    if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                    if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                    doneN = abs(lumaEndN) >= gradientScaled;
+                    doneP = abs(lumaEndP) >= gradientScaled;
+                    if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
+                    if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
+                    doneNP = (!doneN) || (!doneP);
+                    if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
+                    if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
+/*--------------------------------------------------------------------------*/
+                    #if (FXAA_QUALITY__PS > 12)
+                    if(doneNP) {
+                        if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+                        if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+                        if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+                        if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+                        doneN = abs(lumaEndN) >= gradientScaled;
+                        doneP = abs(lumaEndP) >= gradientScaled;
+                        if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
+                        if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
+                        doneNP = (!doneN) || (!doneP);
+                        if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
+                        if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
+/*--------------------------------------------------------------------------*/
+                    }
+                    #endif
+/*--------------------------------------------------------------------------*/
+                }
+                #endif
+/*--------------------------------------------------------------------------*/
+            }
+            #endif
+/*--------------------------------------------------------------------------*/
+        }
+        #endif
+/*--------------------------------------------------------------------------*/
+    }
+    #endif
+/*--------------------------------------------------------------------------*/
+                        }
+                        #endif
+/*--------------------------------------------------------------------------*/
+                    }
+                    #endif
+/*--------------------------------------------------------------------------*/
+                }
+                #endif
+/*--------------------------------------------------------------------------*/
+            }
+            #endif
+/*--------------------------------------------------------------------------*/
+        }
+        #endif
+/*--------------------------------------------------------------------------*/
+    }
+/*--------------------------------------------------------------------------*/
+    float dstN = posM.x - posN.x;
+    float dstP = posP.x - posM.x;
+    if(!horzSpan) dstN = posM.y - posN.y;
+    if(!horzSpan) dstP = posP.y - posM.y;
+/*--------------------------------------------------------------------------*/
+    bool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
+    float spanLength = (dstP + dstN);
+    bool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
+    float spanLengthRcp = 1.0/spanLength;
+/*--------------------------------------------------------------------------*/
+    bool directionN = dstN < dstP;
+    float dst = min(dstN, dstP);
+    bool goodSpan = directionN ? goodSpanN : goodSpanP;
+    float subpixG = subpixF * subpixF;
+    float pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
+    float subpixH = subpixG * fxaaQualitySubpix;
+/*--------------------------------------------------------------------------*/
+    float pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
+    float pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
+    if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
+    if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
+    return FxaaTexTop(tex, posM);
+}
+/*==========================================================================*/
+
+/*============================================================================
+
+                      Urho3D Vertex- and Pixelshader
+                      
+============================================================================*/
+
+void VS(float4 iPos : POSITION,
+    out float4 oPos : POSITION,
+    out float2 oScreenPos : TEXCOORD0)
+{
+    float4x3 modelMatrix = iModelMatrix;
+    float3 worldPos = GetWorldPos(modelMatrix);
+    oPos = GetClipPos(worldPos);
+    oScreenPos = GetScreenPosPreDiv(oPos);
+}
+
+void PS(float2 iScreenPos : TEXCOORD0,
+    out float4 oColor : COLOR0)
+{
+    float2 rcpFrame = float2(cGBufferInvSize.x, cGBufferInvSize.y);
+
+    oColor = float4(FxaaPixelShader(
+        iScreenPos,							// float2 pos,
+        sDiffMap,							// sampler2D tex,
+        rcpFrame,							// float2 fxaaQualityRcpFrame,
+        0.75f,									// float fxaaQualitySubpix,
+        0.166f,									// float fxaaQualityEdgeThreshold,
+        0.0833f								// float fxaaQualityEdgeThresholdMin
+    ).rgb, 1.0);
+}
+

+ 3 - 3
Bin/Data/LuaScripts/09_MultipleViewports.lua

@@ -138,11 +138,11 @@ function SetupViewports()
     -- disabled.
     -- disabled.
     local effectRenderPath = viewport:GetRenderPath():Clone()
     local effectRenderPath = viewport:GetRenderPath():Clone()
     effectRenderPath:Append(cache:GetResource("XMLFile", "PostProcess/Bloom.xml"))
     effectRenderPath:Append(cache:GetResource("XMLFile", "PostProcess/Bloom.xml"))
-    effectRenderPath:Append(cache:GetResource("XMLFile", "PostProcess/EdgeFilter.xml"))
+    effectRenderPath:Append(cache:GetResource("XMLFile", "PostProcess/FXAA2.xml"))
     -- Make the bloom mixing parameter more pronounced
     -- Make the bloom mixing parameter more pronounced
     effectRenderPath:SetShaderParameter("BloomMix", Variant(Vector2(0.9, 0.6)))
     effectRenderPath:SetShaderParameter("BloomMix", Variant(Vector2(0.9, 0.6)))
     effectRenderPath:SetEnabled("Bloom", false)
     effectRenderPath:SetEnabled("Bloom", false)
-    effectRenderPath:SetEnabled("EdgeFilter", false)
+    effectRenderPath:SetEnabled("FXAA", false)
     viewport:SetRenderPath(effectRenderPath)
     viewport:SetRenderPath(effectRenderPath)
 
 
     -- Set up the rear camera viewport on top of the front view ("rear view mirror")
     -- Set up the rear camera viewport on top of the front view ("rear view mirror")
@@ -201,7 +201,7 @@ function MoveCamera(timeStep)
         effectRenderPath:ToggleEnabled("Bloom")
         effectRenderPath:ToggleEnabled("Bloom")
     end
     end
     if input:GetKeyPress(KEY_F) then
     if input:GetKeyPress(KEY_F) then
-        effectRenderPath:ToggleEnabled("EdgeFilter")
+        effectRenderPath:ToggleEnabled("FXAA")
     end
     end
 
 
     -- Toggle debug geometry with space
     -- Toggle debug geometry with space

+ 0 - 6
Bin/Data/PostProcess/EdgeFilter.xml

@@ -1,6 +0,0 @@
-<renderpath>
-    <command type="quad" tag="EdgeFilter" vs="EdgeFilter" ps="EdgeFilter" output="viewport">
-        <texture unit="diffuse" name="viewport" />
-        <parameter name="EdgeFilterParams" value="0.4 0.5 0.75" />
-    </command>
-</renderpath>

+ 0 - 5
Bin/Data/PostProcess/FXAA.xml

@@ -1,5 +0,0 @@
-<renderpath>
-    <command type="quad" tag="FXAA" vs="FXAA" ps="FXAA" output="viewport">
-        <texture unit="diffuse" name="viewport" />
-    </command>
-</renderpath>

+ 6 - 0
Bin/Data/PostProcess/FXAA2.xml

@@ -0,0 +1,6 @@
+<renderpath>
+    <command type="quad" tag="FXAA" vs="FXAA2" ps="FXAA2" output="viewport">
+        <texture unit="diffuse" name="viewport" />
+        <parameter name="FXAAParams" value="0.4 0.5 0.75" />
+    </command>
+</renderpath>

+ 5 - 0
Bin/Data/PostProcess/FXAA3.xml

@@ -0,0 +1,5 @@
+<renderpath>
+    <command type="quad" tag="FXAA" vs="FXAA3" ps="FXAA3" psdefines="FXAA_QUALITY__PRESET=12" output="viewport">
+        <texture unit="diffuse" name="viewport" />
+    </command>
+</renderpath>

+ 3 - 3
Bin/Data/Scripts/09_MultipleViewports.as

@@ -143,11 +143,11 @@ void SetupViewports()
     // disabled.
     // disabled.
     RenderPath@ effectRenderPath = viewport.renderPath.Clone();
     RenderPath@ effectRenderPath = viewport.renderPath.Clone();
     effectRenderPath.Append(cache.GetResource("XMLFile", "PostProcess/Bloom.xml"));
     effectRenderPath.Append(cache.GetResource("XMLFile", "PostProcess/Bloom.xml"));
-    effectRenderPath.Append(cache.GetResource("XMLFile", "PostProcess/EdgeFilter.xml"));
+    effectRenderPath.Append(cache.GetResource("XMLFile", "PostProcess/FXAA2.xml"));
     // Make the bloom mixing parameter more pronounced
     // Make the bloom mixing parameter more pronounced
     effectRenderPath.shaderParameters["BloomMix"] = Variant(Vector2(0.9f, 0.6f));
     effectRenderPath.shaderParameters["BloomMix"] = Variant(Vector2(0.9f, 0.6f));
     effectRenderPath.SetEnabled("Bloom", false);
     effectRenderPath.SetEnabled("Bloom", false);
-    effectRenderPath.SetEnabled("EdgeFilter", false);
+    effectRenderPath.SetEnabled("FXAA", false);
     viewport.renderPath = effectRenderPath;
     viewport.renderPath = effectRenderPath;
 
 
     // Set up the rear camera viewport on top of the front view ("rear view mirror")
     // Set up the rear camera viewport on top of the front view ("rear view mirror")
@@ -202,7 +202,7 @@ void MoveCamera(float timeStep)
     if (input.keyPress['B'])
     if (input.keyPress['B'])
         effectRenderPath.ToggleEnabled("Bloom");
         effectRenderPath.ToggleEnabled("Bloom");
     if (input.keyPress['F'])
     if (input.keyPress['F'])
-        effectRenderPath.ToggleEnabled("EdgeFilter");
+        effectRenderPath.ToggleEnabled("FXAA");
 
 
     // Toggle debug geometry with space
     // Toggle debug geometry with space
     if (input.keyPress[KEY_SPACE])
     if (input.keyPress[KEY_SPACE])

+ 1 - 0
Docs/Urho3D.dox

@@ -85,6 +85,7 @@ Urho3D development, contributions and bugfixes by:
 - Joshua Tippetts
 - Joshua Tippetts
 - Daniel Wiberg
 - Daniel Wiberg
 - Steven Zhang
 - Steven Zhang
+- AGreatFish
 - Firegorilla
 - Firegorilla
 - Magic.Lixin
 - Magic.Lixin
 - Mike3D
 - Mike3D

+ 2 - 1
Readme.txt

@@ -38,6 +38,7 @@ Urho3D development, contributions and bugfixes by:
 - Joshua Tippetts
 - Joshua Tippetts
 - Daniel Wiberg
 - Daniel Wiberg
 - Steven Zhang
 - Steven Zhang
+- AGreatFish
 - Firegorilla
 - Firegorilla
 - Magic.Lixin
 - Magic.Lixin
 - Mike3D
 - Mike3D
@@ -687,4 +688,4 @@ V1.1    - Object and scene model refactoring.
         - Added OpenGL and cross-platform support.
         - Added OpenGL and cross-platform support.
         - Switched to kNet library for networking.
         - Switched to kNet library for networking.
 
 
-V1.0    - Original release.
+V1.0    - Original release.

+ 3 - 3
Source/Samples/09_MultipleViewports/MultipleViewports.cpp

@@ -199,11 +199,11 @@ void MultipleViewports::SetupViewports()
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     SharedPtr<RenderPath> effectRenderPath = viewport->GetRenderPath()->Clone();
     SharedPtr<RenderPath> effectRenderPath = viewport->GetRenderPath()->Clone();
     effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/Bloom.xml"));
     effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/Bloom.xml"));
-    effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/EdgeFilter.xml"));
+    effectRenderPath->Append(cache->GetResource<XMLFile>("PostProcess/FXAA2.xml"));
     // Make the bloom mixing parameter more pronounced
     // Make the bloom mixing parameter more pronounced
     effectRenderPath->SetShaderParameter("BloomMix", Vector2(0.9f, 0.6f));
     effectRenderPath->SetShaderParameter("BloomMix", Vector2(0.9f, 0.6f));
     effectRenderPath->SetEnabled("Bloom", false);
     effectRenderPath->SetEnabled("Bloom", false);
-    effectRenderPath->SetEnabled("EdgeFilter", false);
+    effectRenderPath->SetEnabled("FXAA", false);
     viewport->SetRenderPath(effectRenderPath);
     viewport->SetRenderPath(effectRenderPath);
     
     
     // Set up the rear camera viewport on top of the front view ("rear view mirror")
     // Set up the rear camera viewport on top of the front view ("rear view mirror")
@@ -260,7 +260,7 @@ void MultipleViewports::MoveCamera(float timeStep)
     if (input->GetKeyPress('B'))
     if (input->GetKeyPress('B'))
         effectRenderPath->ToggleEnabled("Bloom");
         effectRenderPath->ToggleEnabled("Bloom");
     if (input->GetKeyPress('F'))
     if (input->GetKeyPress('F'))
-        effectRenderPath->ToggleEnabled("EdgeFilter");
+        effectRenderPath->ToggleEnabled("FXAA");
     
     
     // Toggle debug geometry with space
     // Toggle debug geometry with space
     if (input->GetKeyPress(KEY_SPACE))
     if (input->GetKeyPress(KEY_SPACE))