Fxaa broken in Godot 2.1.2

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By leoyi
:warning: Old Version Published before Godot 3 was released.

FXAA makes edges of objects noticeably grainy. I tried adding a world environment node in the scene with FXAA on. I also tried adding a world environment in the camera settings. Both produced the same results. Tried different lights, or just ambient light, toggled the shadows, etc. Still didn’t work.

enter image description here
Further objects

enter image description here
Closer objects

I downloaded another developer’s game that is made in Godot (Verdigris by germanalen), it shows the same grainy effect that happens when FXAA is turned on. I also tested this game on a friend’s PC, the same results can be seen. (My PC is using Nvidia)

As a last resort, I converted godot’s FXAA code from github to godot’s shading language and applied it to a ViewPortSprite. I managed to get the same broken FXAA effect. Tweaking the values did make noticeable changes, but it still looks grainy. If someone has any solutions, I appreciate it. (Praying for Godot 3.0)

For what it’s worth, here is the converted shader’s code:

float FXAA_REDUCE_MIN =  (1.0/ 128.0);
float FXAA_REDUCE_MUL =  (1.0 / 8.0);
float FXAA_SPAN_MAX  =  8;
vec2 resolution=vec2(1024,600);
float val=1.0;
vec2 inverseVP = vec2(1.0 / resolution.x, 1.0 / resolution.y);
vec3 rgbNW = texscreen(SCREEN_UV + (vec2(-val, -val) * inverseVP)).xyz;
vec3 rgbNE = texscreen(SCREEN_UV + (vec2(val, -val) * inverseVP)).xyz;
vec3 rgbSW = texscreen(SCREEN_UV + (vec2(-val, val) * inverseVP)).xyz;
vec3 rgbSE = texscreen(SCREEN_UV+ (vec2(val, val) * inverseVP)).xyz;
vec3 rgbM  =texscreen(SCREEN_UV);
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
float lumaNE = dot(rgbNE, luma);
float lumaSW = dot(rgbSW, luma);
float lumaSE = dot(rgbSE, luma);
float lumaM  = dot(rgbM,  luma);
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));

vec2 dir;
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
                    (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 * rcpDirMin)) * inverseVP;

vec3 rgbA = (1.0/2.0) * (
           texscreen(SCREEN_UV + dir * (1.0/3.0 - 0.5)).xyz +
           texscreen(SCREEN_UV + dir * (2.0/3.0 - 0.5)).xyz);
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
           texscreen(SCREEN_UV + dir * (0.0/3.0 - 0.5)).xyz +
            texscreen(SCREEN_UV + dir * (3.0/3.0 - 0.5)).xyz);
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax)){
     COLOR.rgb = rgbA;
}else{
   COLOR.rgb  = rgbB;
}

That MSAA implementation looks good, I want it. It’s not merged into the current Godot though. I have no idea how to use it (need to do a manual compilation of Godot?). It would be ideal if there’s a fix to the current FXAA.

leoyi | 2017-04-10 23:38

Nice. I compiled latest Godot build following this tutorial Compiling for Windows — Godot Engine (stable) documentation in English
and found that there is an option for MSAA in project settings, it works pretty good. Too bad the build still buggy, can’t import .dae files properly.

leoyi | 2017-04-22 18:10