diff --git a/.gitignore b/.gitignore index 56f10b1afd70..7fedcf343505 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ Thumbs.db /Source/Shaders/*.js /Source/Shaders/*/*.js /Source/Shaders/*/*/*.js +/Source/ThirdParty/Shaders/*.js /Specs/SpecList.js diff --git a/CHANGES.md b/CHANGES.md index 818a2fc362f8..586150da100a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ Change Log * Added `disableDepthTestDistance` to billboards, points and labels. This sets the distance to the camera where the depth test will be disabled. Setting it to zero (the default) will alwasy enable the depth test. Setting it to `Number.POSITVE_INFINITY` will never enabled the depth test. Also added `scene.minimumDisableDepthTestDistance` to change the default value from zero. [#5166](https://github.com/AnalyticalGraphicsInc/cesium/pull/5166) * Fixed issue with displaying `MapboxImageryProvider` default token error message [#5191](https://github.com/AnalyticalGraphicsInc/cesium/pull/5191) * Added a `depthFailMaterial` property to line entities, which is the material used to render the line when it fails the depth test. [#5160](https://github.com/AnalyticalGraphicsInc/cesium/pull/5160) +* Upgrade FXAA to version 3.11. [#5200](https://github.com/AnalyticalGraphicsInc/cesium/pull/5200) ### 1.32 - 2017-04-03 diff --git a/LICENSE.md b/LICENSE.md index e95d8ff924ac..13868a3dbfae 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -214,11 +214,11 @@ https://gist.github.com/banksean/300494 > > THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 Image-Based Anti-Aliasing +### NVIDIA GameWorks Graphics Samples -https://developer.nvidia.com/nvidia-graphics-sdk-11-direct3d +https://github.com/NVIDIAGameWorks/GraphicsSamples -> Copyright 2011 NVIDIA Corporation +> Copyright 2016 NVIDIA Corporation > > BY DOWNLOADING THE SOFTWARE AND OTHER AVAILABLE MATERIALS, YOU ("DEVELOPER") AGREE TO BE BOUND BY THE FOLLOWING TERMS AND CONDITIONS > diff --git a/Source/Scene/FXAA.js b/Source/Scene/FXAA.js index 783bb7485c49..46f1342678a1 100644 --- a/Source/Scene/FXAA.js +++ b/Source/Scene/FXAA.js @@ -12,8 +12,13 @@ define([ '../Renderer/Renderbuffer', '../Renderer/RenderbufferFormat', '../Renderer/RenderState', + '../Renderer/Sampler', '../Renderer/Texture', - '../Shaders/PostProcessFilters/FXAA' + '../Renderer/TextureMagnificationFilter', + '../Renderer/TextureMinificationFilter', + '../Renderer/TextureWrap', + '../Shaders/PostProcessFilters/FXAA', + '../ThirdParty/Shaders/FXAA3_11' ], function( BoundingRectangle, Cartesian2, @@ -27,14 +32,19 @@ define([ Renderbuffer, RenderbufferFormat, RenderState, + Sampler, Texture, - FXAAFS) { + TextureMagnificationFilter, + TextureMinificationFilter, + TextureWrap, + FXAAFS, + FXAA3_11) { 'use strict'; /** * @private */ - function FXAA(context) { + function FXAA() { this._texture = undefined; this._depthStencilTexture = undefined; this._depthStencilRenderbuffer = undefined; @@ -50,6 +60,8 @@ define([ owner : this }); this._clearCommand = clearCommand; + + this._qualityPreset = 39; } function destroyResources(fxaa) { @@ -85,7 +97,13 @@ define([ width : width, height : height, pixelFormat : PixelFormat.RGBA, - pixelDatatype : PixelDatatype.UNSIGNED_BYTE + pixelDatatype : PixelDatatype.UNSIGNED_BYTE, + sampler : new Sampler({ + wrapS : TextureWrap.CLAMP_TO_EDGE, + wrapT : TextureWrap.CLAMP_TO_EDGE, + minificationFilter : TextureMinificationFilter.LINEAR, + magnificationFilter : TextureMagnificationFilter.LINEAR + }) }); if (context.depthTexture) { @@ -119,7 +137,12 @@ define([ } if (!defined(this._command)) { - this._command = context.createViewportQuadCommand(FXAAFS, { + var fs = + '#define FXAA_QUALITY_PRESET ' + this._qualityPreset + '\n' + + FXAA3_11 + '\n' + + FXAAFS; + + this._command = context.createViewportQuadCommand(fs, { owner : this }); } @@ -137,13 +160,13 @@ define([ if (textureChanged) { var that = this; - var step = new Cartesian2(1.0 / this._texture.width, 1.0 / this._texture.height); + var rcpFrame = new Cartesian2(1.0 / this._texture.width, 1.0 / this._texture.height); this._command.uniformMap = { u_texture : function() { return that._texture; }, - u_step : function() { - return step; + u_fxaaQualityRcpFrame : function() { + return rcpFrame; } }; } diff --git a/Source/Shaders/CompositeOITFS.glsl b/Source/Shaders/CompositeOITFS.glsl index b2efbceba787..dbe6c46d5801 100644 --- a/Source/Shaders/CompositeOITFS.glsl +++ b/Source/Shaders/CompositeOITFS.glsl @@ -3,7 +3,7 @@ * - http://jcgt.org/published/0002/02/09/ * - http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html */ - + uniform sampler2D u_opaque; uniform sampler2D u_accumulation; uniform sampler2D u_revealage; @@ -15,12 +15,17 @@ void main() vec4 opaque = texture2D(u_opaque, v_textureCoordinates); vec4 accum = texture2D(u_accumulation, v_textureCoordinates); float r = texture2D(u_revealage, v_textureCoordinates).r; - + #ifdef MRT vec4 transparent = vec4(accum.rgb / clamp(r, 1e-4, 5e4), accum.a); #else vec4 transparent = vec4(accum.rgb / clamp(accum.a, 1e-4, 5e4), r); #endif - + gl_FragColor = (1.0 - transparent.a) * transparent + transparent.a * opaque; + + if (opaque != czm_backgroundColor) + { + gl_FragColor.a = 1.0; + } } diff --git a/Source/Shaders/PostProcessFilters/FXAA.glsl b/Source/Shaders/PostProcessFilters/FXAA.glsl index edd2b911e4be..09067f48970e 100644 --- a/Source/Shaders/PostProcessFilters/FXAA.glsl +++ b/Source/Shaders/PostProcessFilters/FXAA.glsl @@ -1,245 +1,21 @@ -/** - * @license - * Copyright (c) 2011 NVIDIA Corporation. All rights reserved. - * - * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED - * *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS - * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT,IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA - * OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT, OR - * CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS - * OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY - * OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, - * EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - */ - -/* -FXAA_PRESET - Choose compile-in knob preset 0-5. ------------------------------------------------------------------------------- -FXAA_EDGE_THRESHOLD - The minimum amount of local contrast required - to apply algorithm. - 1.0/3.0 - too little - 1.0/4.0 - good start - 1.0/8.0 - applies to more edges - 1.0/16.0 - overkill ------------------------------------------------------------------------------- -FXAA_EDGE_THRESHOLD_MIN - Trims the algorithm from processing darks. - Perf optimization. - 1.0/32.0 - visible limit (smaller isn't visible) - 1.0/16.0 - good compromise - 1.0/12.0 - upper limit (seeing artifacts) ------------------------------------------------------------------------------- -FXAA_SEARCH_STEPS - Maximum number of search steps for end of span. ------------------------------------------------------------------------------- -FXAA_SEARCH_THRESHOLD - Controls when to stop searching. - 1.0/4.0 - seems to be the best quality wise ------------------------------------------------------------------------------- -FXAA_SUBPIX_TRIM - Controls sub-pixel aliasing removal. - 1.0/2.0 - low removal - 1.0/3.0 - medium removal - 1.0/4.0 - default removal - 1.0/8.0 - high removal - 0.0 - complete removal ------------------------------------------------------------------------------- -FXAA_SUBPIX_CAP - Insures fine detail is not completely removed. - This is important for the transition of sub-pixel detail, - like fences and wires. - 3.0/4.0 - default (medium amount of filtering) - 7.0/8.0 - high amount of filtering - 1.0 - no capping of sub-pixel aliasing removal -*/ - -#ifndef FXAA_PRESET - #define FXAA_PRESET 3 -#endif -#if (FXAA_PRESET == 3) - #define FXAA_EDGE_THRESHOLD (1.0/8.0) - #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) - #define FXAA_SEARCH_STEPS 16 - #define FXAA_SEARCH_THRESHOLD (1.0/4.0) - #define FXAA_SUBPIX_CAP (3.0/4.0) - #define FXAA_SUBPIX_TRIM (1.0/4.0) -#endif -#if (FXAA_PRESET == 4) - #define FXAA_EDGE_THRESHOLD (1.0/8.0) - #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) - #define FXAA_SEARCH_STEPS 24 - #define FXAA_SEARCH_THRESHOLD (1.0/4.0) - #define FXAA_SUBPIX_CAP (3.0/4.0) - #define FXAA_SUBPIX_TRIM (1.0/4.0) -#endif -#if (FXAA_PRESET == 5) - #define FXAA_EDGE_THRESHOLD (1.0/8.0) - #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0) - #define FXAA_SEARCH_STEPS 32 - #define FXAA_SEARCH_THRESHOLD (1.0/4.0) - #define FXAA_SUBPIX_CAP (3.0/4.0) - #define FXAA_SUBPIX_TRIM (1.0/4.0) -#endif - -#define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM)) - -// Return the luma, the estimation of luminance from rgb inputs. -// This approximates luma using one FMA instruction, -// skipping normalization and tossing out blue. -// FxaaLuma() will range 0.0 to 2.963210702. -float FxaaLuma(vec3 rgb) { - return rgb.y * (0.587/0.299) + rgb.x; -} - -vec3 FxaaLerp3(vec3 a, vec3 b, float amountOfA) { - return (vec3(-amountOfA) * b) + ((a * vec3(amountOfA)) + b); -} - -vec4 FxaaTexOff(sampler2D tex, vec2 pos, ivec2 off, vec2 rcpFrame) { - float x = pos.x + float(off.x) * rcpFrame.x; - float y = pos.y + float(off.y) * rcpFrame.y; - return texture2D(tex, vec2(x, y)); -} - -// pos is the output of FxaaVertexShader interpolated across screen. -// xy -> actual texture position {0.0 to 1.0} -// rcpFrame should be a uniform equal to {1.0/frameWidth, 1.0/frameHeight} -vec3 FxaaPixelShader(vec2 pos, sampler2D tex, vec2 rcpFrame) -{ - vec3 rgbN = FxaaTexOff(tex, pos.xy, ivec2( 0,-1), rcpFrame).xyz; - vec3 rgbW = FxaaTexOff(tex, pos.xy, ivec2(-1, 0), rcpFrame).xyz; - vec3 rgbM = FxaaTexOff(tex, pos.xy, ivec2( 0, 0), rcpFrame).xyz; - vec3 rgbE = FxaaTexOff(tex, pos.xy, ivec2( 1, 0), rcpFrame).xyz; - vec3 rgbS = FxaaTexOff(tex, pos.xy, ivec2( 0, 1), rcpFrame).xyz; - - float lumaN = FxaaLuma(rgbN); - float lumaW = FxaaLuma(rgbW); - float lumaM = FxaaLuma(rgbM); - float lumaE = FxaaLuma(rgbE); - float lumaS = FxaaLuma(rgbS); - float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE))); - float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE))); - - float range = rangeMax - rangeMin; - if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) - { - return rgbM; - } - - vec3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS; - - float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25; - float rangeL = abs(lumaL - lumaM); - float blendL = max(0.0, (rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE; - blendL = min(FXAA_SUBPIX_CAP, blendL); - - vec3 rgbNW = FxaaTexOff(tex, pos.xy, ivec2(-1,-1), rcpFrame).xyz; - vec3 rgbNE = FxaaTexOff(tex, pos.xy, ivec2( 1,-1), rcpFrame).xyz; - vec3 rgbSW = FxaaTexOff(tex, pos.xy, ivec2(-1, 1), rcpFrame).xyz; - vec3 rgbSE = FxaaTexOff(tex, pos.xy, ivec2( 1, 1), rcpFrame).xyz; - rgbL += (rgbNW + rgbNE + rgbSW + rgbSE); - rgbL *= vec3(1.0/9.0); - - float lumaNW = FxaaLuma(rgbNW); - float lumaNE = FxaaLuma(rgbNE); - float lumaSW = FxaaLuma(rgbSW); - float lumaSE = FxaaLuma(rgbSE); - - float edgeVert = - abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) + - abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) + - abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE)); - float edgeHorz = - abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) + - abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) + - abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE)); - - bool horzSpan = edgeHorz >= edgeVert; - float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x; - - if(!horzSpan) - { - lumaN = lumaW; - lumaS = lumaE; - } - - float gradientN = abs(lumaN - lumaM); - float gradientS = abs(lumaS - lumaM); - lumaN = (lumaN + lumaM) * 0.5; - lumaS = (lumaS + lumaM) * 0.5; - - if (gradientN < gradientS) - { - lumaN = lumaS; - lumaN = lumaS; - gradientN = gradientS; - lengthSign *= -1.0; - } - - vec2 posN; - posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5); - posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0); - - gradientN *= FXAA_SEARCH_THRESHOLD; - - vec2 posP = posN; - vec2 offNP = horzSpan ? vec2(rcpFrame.x, 0.0) : vec2(0.0, rcpFrame.y); - float lumaEndN = lumaN; - float lumaEndP = lumaN; - bool doneN = false; - bool doneP = false; - posN += offNP * vec2(-1.0, -1.0); - posP += offNP * vec2( 1.0, 1.0); - - for(int i = 0; i < FXAA_SEARCH_STEPS; i++) { - if(!doneN) - { - lumaEndN = FxaaLuma(texture2D(tex, posN.xy).xyz); - } - if(!doneP) - { - lumaEndP = FxaaLuma(texture2D(tex, posP.xy).xyz); - } - - doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN); - doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN); - - if(doneN && doneP) - { - break; - } - if(!doneN) - { - posN -= offNP; - } - if(!doneP) - { - posP += offNP; - } - } - - float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y; - float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y; - bool directionN = dstN < dstP; - lumaEndN = directionN ? lumaEndN : lumaEndP; - - if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0)) - { - lengthSign = 0.0; - } - - - float spanLength = (dstP + dstN); - dstN = directionN ? dstN : dstP; - float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign; - vec3 rgbF = texture2D(tex, vec2( - pos.x + (horzSpan ? 0.0 : subPixelOffset), - pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz; - return FxaaLerp3(rgbL, rgbF, blendL); -} +varying vec2 v_textureCoordinates; uniform sampler2D u_texture; -uniform vec2 u_step; +uniform vec2 u_fxaaQualityRcpFrame; -varying vec2 v_textureCoordinates; +const float fxaaQualitySubpix = 0.5; +const float fxaaQualityEdgeThreshold = 0.125; +const float fxaaQualityEdgeThresholdMin = 0.0833; void main() { - gl_FragColor = vec4(FxaaPixelShader(v_textureCoordinates, u_texture, u_step), 1.0); + vec4 color = FxaaPixelShader( + v_textureCoordinates, + u_texture, + u_fxaaQualityRcpFrame, + fxaaQualitySubpix, + fxaaQualityEdgeThreshold, + fxaaQualityEdgeThresholdMin); + float alpha = texture2D(u_texture, v_textureCoordinates).a; + gl_FragColor = vec4(color.rgb, alpha); } diff --git a/Source/ThirdParty/Shaders/FXAA3_11.glsl b/Source/ThirdParty/Shaders/FXAA3_11.glsl new file mode 100644 index 000000000000..3499e14f1cfa --- /dev/null +++ b/Source/ThirdParty/Shaders/FXAA3_11.glsl @@ -0,0 +1,648 @@ +/** + * @license + * Copyright (c) 2014-2015, 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 GameWorks Graphics Samples GitHub link: https://github.com/NVIDIAGameWorks/GraphicsSamples +// Original FXAA 3.11 shader link: https://github.com/NVIDIAGameWorks/GraphicsSamples/blob/master/samples/es3-kepler/FXAA/FXAA3_11.h + +// Steps used to integrate into Cesium: +// * The following defines are set: +// #define FXAA_PC 1 +// #define FXAA_WEBGL_1 1 +// #define FXAA_GREEN_AS_LUMA 1 +// #define FXAA_EARLY_EXIT 1 +// #define FXAA_GLSL_120 1 +// * All other preprocessor directives besides the FXAA_QUALITY__P* directives were removed. +// * Double underscores are invalid for preprocessor directives so replace them with a single underscore. Replace +// /FXAA_QUALITY__P(.*)/g with /FXAA_QUALITY__P$1/. +// * There are no implicit conversions from ivec* to vec* so replace: +// #define FxaaInt2 ivec2 +// with +// #define FxaaInt2 vec2 +// * The texture2DLod function is only available in vertex shaders so replace: +// #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) +// #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) +// with +// #define FxaaTexTop(t, p) texture2D(t, p) +// #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r)) +// * FXAA_QUALITY_PRESET is prepended in the javascript code. We may want to expose that setting in the future. +// * The following parameters to FxaaPixelShader are unused and can be removed: +// fxaaConsolePosPos +// fxaaConsoleRcpFrameOpt +// fxaaConsoleRcpFrameOpt2 +// fxaaConsole360RcpFrameOpt2 +// fxaaConsoleEdgeSharpness +// fxaaConsoleEdgeThreshold +// fxaaConsoleEdgeThresholdMi +// fxaaConsole360ConstDir + +// +// 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 + + +#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 +#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 +#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 + +#define FxaaBool bool +#define FxaaFloat float +#define FxaaFloat2 vec2 +#define FxaaFloat3 vec3 +#define FxaaFloat4 vec4 +#define FxaaHalf float +#define FxaaHalf2 vec2 +#define FxaaHalf3 vec3 +#define FxaaHalf4 vec4 +#define FxaaInt2 vec2 +#define FxaaTex sampler2D + +#define FxaaSat(x) clamp(x, 0.0, 1.0) +#define FxaaTexTop(t, p) texture2D(t, p) +#define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r)) + +FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } + +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 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) + FxaaTex tex, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 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 + FxaaFloat 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) + FxaaFloat 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. + FxaaFloat fxaaQualityEdgeThresholdMin +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #define lumaM rgbyM.y + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 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; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY_P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY_P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY_P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY_P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY_P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY_P1; + FxaaBool 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 +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); +} diff --git a/gulpfile.js b/gulpfile.js index 45a2f61da48c..13be1624c703 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -81,6 +81,7 @@ var filesToClean = ['Source/Cesium.js', 'Build', 'Instrumented', 'Source/Shaders/**/*.js', + 'Source/ThirdParty/Shaders/*.js', 'Specs/SpecList.js', 'Apps/Sandcastle/jsHintOptions.js', 'Apps/Sandcastle/gallery/gallery-index.js', @@ -957,7 +958,7 @@ function glslToJavaScript(minify, minifyStateFilePath) { // we still are using from the set, then delete any files remaining in the set. var leftOverJsFiles = {}; - globby.sync(['Source/Shaders/**/*.js']).forEach(function(file) { + globby.sync(['Source/Shaders/**/*.js', 'Source/ThirdParty/Shaders/*.js']).forEach(function(file) { leftOverJsFiles[path.normalize(file)] = true; }); @@ -965,7 +966,7 @@ function glslToJavaScript(minify, minifyStateFilePath) { var builtinConstants = []; var builtinStructs = []; - var glslFiles = globby.sync(['Source/Shaders/**/*.glsl']); + var glslFiles = globby.sync(['Source/Shaders/**/*.glsl', 'Source/ThirdParty/Shaders/*.glsl']); glslFiles.forEach(function(glslFile) { glslFile = path.normalize(glslFile); var baseName = path.basename(glslFile, '.glsl');