Skip to content

Commit

Permalink
expose fxaa params
Browse files Browse the repository at this point in the history
  • Loading branch information
turbo committed Nov 14, 2019
1 parent cf369be commit 5c6f40e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This is a port of NVIDIA's original FXAA v2 shader (the console version), with further pre-compute optimizations added by Matt DesLauriers. In short, FXAA is a single-pass, 1:1 anti-aliasing post-processing effect. Compared to straight super-sampling or MSAA, it has a lower quality, but is much faster. Love2D's MSAA was too slow for a project I'm working on, so I quickly hacked this together based on Matt's glslify shader.
This is a port of NVIDIA's original FXAA v2 shader (the console version), with further pre-compute optimizations added by Matt DesLauriers. In short, FXAA is a single-pass, 1:1 anti-aliasing post-processing effect. Compared to straight super-sampling or MSAA, it has a lower quality, but is much faster. Love2D's MSAA was too slow for a project I'm working on, so I quickly hacked this together based on Matt's glslify shader. I've added an optional sharpening stage, which uses a very simple algorithm.

I found that (on my linux machine with NVIDIA drivers), the shader *must* be applied to a canvas if `window.setMode` is used *at all*. Don't ask me why. You can finetune the FXAA params in the shader code (or convert them to sent values to allow runtime changes). Read the paper to learn what they mean.
`main.moon` contains an example class `FXAACanvas`, which wraps canvas draw calls and applies FXAA and sharpening on `render`. You can fine tune all FXAA params and the sharpening strength, as well as the number of FXAA passes (uses nested canvas render targets).

Here's a screenshot of the demo file (single pass, left is FXAA, right is original):
Here's a screenshot of the demo file (click to view full size):

![](/screenshot.png)
28 changes: 16 additions & 12 deletions fxaa.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/

#ifndef FXAA_REDUCE_MIN
#define FXAA_REDUCE_MIN (1.0/ 128.0)
#endif
#ifndef FXAA_REDUCE_MUL
#define FXAA_REDUCE_MUL (1.0 / 8.0)
#endif
#ifndef FXAA_SPAN_MAX
#define FXAA_SPAN_MAX 8.0
#endif
// #ifndef fxaa_reduce_min
// #define fxaa_reduce_min (1.0/ 128.0)
// #endif
// #ifndef fxaa_reduce_mul
// #define fxaa_reduce_mul (1.0 / 8.0)
// #endif
// #ifndef fxaa_span_max
// #define fxaa_span_max 8.0
// #endif

uniform float fxaa_reduce_min;
uniform float fxaa_reduce_mul;
uniform float fxaa_span_max;

varying vec2 v_rgbNW;
varying vec2 v_rgbNE;
Expand Down Expand Up @@ -142,11 +146,11 @@ vec4 fxaa(
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));

float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
(0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
(0.25 * fxaa_reduce_mul), fxaa_reduce_min);

float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
dir = min(vec2(fxaa_span_max, fxaa_span_max),
max(vec2(-fxaa_span_max, -fxaa_span_max),
dir * rcpDirMin)) * inverseVP;

vec3 rgbA = 0.5 * (
Expand Down
8 changes: 7 additions & 1 deletion main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ do
end
self.sharpen = sharpen
self.shader_fxaa = love.graphics.newShader('fxaa.glsl')
do
local _with_0 = self.shader_fxaa
_with_0:send('fxaa_reduce_min', (1.0 / 128.0))
_with_0:send('fxaa_reduce_mul', (1.0 / 8.0))
_with_0:send('fxaa_span_max', 8.0)
end
self.shader_sharpen = love.graphics.newShader('sharpen.glsl')
self.layers = { }
for stage = 1, stages do
Expand Down Expand Up @@ -81,7 +87,7 @@ love.load = function()
love.window.setMode(1024, 1024, {
borderless = true
})
return love.window.setTitle("Mobile FXAA (by NVIDIA/Timothy L. & Meincraft/Armin Ronacher) - Left: FXAA on, Right: Original")
return love.window.setTitle("Mobile FXAA (by NVIDIA/Timothy L. & Meincraft/Armin Ronacher)")
end
local cv = FXAACanvas(512, 512)
local cv2 = FXAACanvas(512, 512, 2)
Expand Down
10 changes: 7 additions & 3 deletions main.moon
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
image = love.graphics.newImage('download.png')

class FXAACanvas

new: (width, height, stages = 1, @sharpen = 0) =>
new: (width, height, stages = 1, @sharpen = 0, reduce_min = 1/128, reduce_mul = 1/8, span_max = 8) =>
@shader_fxaa = love.graphics.newShader('fxaa.glsl')
with @shader_fxaa
\send('fxaa_reduce_min', reduce_min)
\send('fxaa_reduce_mul', reduce_mul)
\send('fxaa_span_max', span_max)

@shader_sharpen = love.graphics.newShader('sharpen.glsl')

@layers = { }
Expand Down Expand Up @@ -53,7 +57,7 @@ love.load = ->
-- vsync: false
})

love.window.setTitle("Mobile FXAA (by NVIDIA/Timothy L. & Meincraft/Armin Ronacher) - Left: FXAA on, Right: Original")
love.window.setTitle("Mobile FXAA (by NVIDIA/Timothy L. & Meincraft/Armin Ronacher)")


cv = FXAACanvas(512, 512)
Expand Down

0 comments on commit 5c6f40e

Please sign in to comment.