Horde3D
http://www.horde3d.org/forums/

FXAA
http://www.horde3d.org/forums/viewtopic.php?f=4&t=1599
Page 1 of 2

Author:  worstplayer [ 27.11.2011, 21:40 ]
Post subject:  FXAA

All games are apparently required by law to have FXAA nowadays :P

This one's based on original FXAA, there's more recent versions, but I really can't see the difference. Feel free to use/modify for your own project.

Image

Code:
[[FS_FXAA]]
// =================================================================================================

uniform sampler2D buf0;
uniform vec2 frameBufSize;
varying vec2 texCoords;

void main( void )
{
   float FXAA_SPAN_MAX = 8.0;
   float FXAA_REDUCE_MUL = 1.0/8.0;
   float FXAA_REDUCE_MIN = 1.0/128.0;

   vec3 rgbNW=texture2D(buf0,texCoords+(vec2(-1.0,-1.0)/frameBufSize)).xyz;
   vec3 rgbNE=texture2D(buf0,texCoords+(vec2(1.0,-1.0)/frameBufSize)).xyz;
   vec3 rgbSW=texture2D(buf0,texCoords+(vec2(-1.0,1.0)/frameBufSize)).xyz;
   vec3 rgbSE=texture2D(buf0,texCoords+(vec2(1.0,1.0)/frameBufSize)).xyz;
   vec3 rgbM=texture2D(buf0,texCoords).xyz;
   
   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)) / frameBufSize;
       
   vec3 rgbA = (1.0/2.0) * (
        texture2D(buf0, texCoords.xy + dir * (1.0/3.0 - 0.5)).xyz +
        texture2D(buf0, texCoords.xy + dir * (2.0/3.0 - 0.5)).xyz);
    vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
        texture2D(buf0, texCoords.xy + dir * (0.0/3.0 - 0.5)).xyz +
        texture2D(buf0, texCoords.xy + dir * (3.0/3.0 - 0.5)).xyz);
    float lumaB = dot(rgbB, luma);

   if((lumaB < lumaMin) || (lumaB > lumaMax)){
      gl_FragColor.xyz=rgbA;
   }else{
      gl_FragColor.xyz=rgbB;
   }
}

Author:  shd [ 28.11.2011, 19:48 ]
Post subject:  Re: FXAA

worstplayer wrote:
All games are apparently required by law to have FXAA nowadays :P

This one's based on original FXAA, there's more recent versions, but I really can't see the difference. Feel free to use/modify for your own project.

Thanks a lot! I've been thinking about which AA use in my game, but i'll start with FXAA then :D

Author:  Mag [ 29.11.2011, 04:10 ]
Post subject:  Re: FXAA

Thanks! cool screen. more games horde3d :D

Author:  eiguckamalda [ 29.11.2011, 17:56 ]
Post subject:  Re: FXAA

Thanks for that shadercode! :)
Included this to my pipeline and it works just fine. But I have one question on this: Are you using the parameter-values shown in this code? I know it's a disadvantage of FXAA, but the image loses very much detail in textures e.g. parallax mappings or other structured surface. Is there a hint or parameter-tweak on reducing this problem a little bit?
Thanks :)

Author:  worstplayer [ 29.11.2011, 18:20 ]
Post subject:  Re: FXAA

Yeah i'm using same parameters. You can reduce blur by increasing FXAA_REDUCE_MUL, but then it will fail on near-vertical and near-horizontal edges where it's most needed. Another alternative would be to put some sharpening filter after it (warpsharp maybe?).

EDIT: you could also try detecting depth buffer edges and adjusting reduce based on that, but I have no idea how well would that work (if at all).

Author:  DarkAngel [ 30.11.2011, 01:20 ]
Post subject:  Re: FXAA

Cool stuff!
We're using FXAA 3.9 on our current game and it's working well for us. We did have problems where it was blurring texture details, but with some parameter tweaking we ended up with a good balance between having it still detect edges but not blur important details.
Also -- on a 5 year old SM3 GPU, we measured it at taking less than 1.6ms on a 720p buffer, which is cheaper than the other methods we tried.

Author:  johannes [ 13.12.2011, 14:33 ]
Post subject:  Re: FXAA

Very cool! Thank you for sharing. :)

Author:  rand [ 01.01.2012, 23:41 ]
Post subject:  Re: FXAA

I added this to the wiki.

However, there is general problem I have with full screen buffers/quads on my system (OSX) though. This has nothing to do with this specific shader, but with something in my general setup since it also appears with the HDR pipeline.

The pipeline that I render to in this example is
Code:
<RenderTarget id="FINALIMAGE" depthBuf="true" numColBufs="1" format="RGBA16F" scale="1.0" maxSamples="0" />

But the image looks very coarse unless I change the "scale" parameter to "4.0" or so, which is not necessary according to the documentation and of course affects the math in the pixel shader. Any ideas on what might be wrong? Or am I just supposed to use a larger "scale" parameter?

Author:  worstplayer [ 03.01.2012, 23:48 ]
Post subject:  Re: FXAA

It appears to be rendered in 256x256, does it still look coarse if you specify exact buffer size, like this?
Code:
<RenderTarget id="FINALIMAGE" depthBuf="true" numColBufs="1" format="RGBA16F" width="1920" height=1080"  maxSamples="0" />

If it looks good after that, you probably forgot to ResizePipelineBuffers after loading the pipeline.

Author:  rand [ 05.01.2012, 23:25 ]
Post subject:  Re: FXAA

That was it. :oops: Thank you. Both options worked.

Here are the results now. I'm not sure about those results. There seem to be some offset pixels. I thought, they might stem from the sampling filter:

Code:
// Samplers
sampler2D buf0 = sampler_state {
   Address = Clamp;
   Filter = None; // <--
};


But changing that to "Trilinear" didn't really remove the pixels:
Image

Is it supposted to look like that, or did I just screw up again? :?

Author:  worstplayer [ 10.01.2012, 15:52 ]
Post subject:  Re: FXAA

Well I'm totally lost here. Similar edges get smoothed just fine in my game. No idea what causes it.

Maybe this could be a part of the problem:
Code:
vec3 luma=vec3(0.299, 0.587, 0.114);
blue has least effect on edge detection, maybe black-on-blue confuses it. Try if adding more weight to blue or changing background color helps. But i'm not really sure, vertical edges seem to look OK.

Author:  rand [ 13.01.2012, 22:05 ]
Post subject:  Re: FXAA

I tried a few things, but in the end nothing worked out. I think it is my setup is still broken somehow. The problem is illustrated here:
Image

It seems that the shader grabs the wrong pixels. There are blue artifact pixels in the solid, where clearly the shader fetched a pixel it was not supposed to. Here is another scene with the edge of a black cube and a non-blue background:
Image
Again you can see, the NorthSouth line is antialiased perfectly, but the EastWest line has weird pixel artifacts at the aliasing steps.

I tried manually changing frameBufSize and the coordinates for rgbNW etc. to somehow fix this, but to no avail. :( The behavior is independent of coloring and this exact shader seems to work fine with other GLSL software.

Author:  rand [ 20.01.2012, 01:17 ]
Post subject:  Re: FXAA

I did some more tests, but am still clueless. :(

My earlier presumption that the wrong pixels are used because my setup was weird was wrong. To test that I used the Chicago sample and made a pixel-perfect shader that draws a grid onto the screen - and that works as it should.
Image
Code:
   gl_FragColor.xyz = texture2D(buf0,texCoords).xyz;
   if (int(texCoords.x*frameBufSize.x)%2==0) {
      gl_FragColor.xyz = vec3(1.0,0.0,0.0);

      if (int(texCoords.y*frameBufSize.y)%2==0) {
         gl_FragColor.xyz = vec3(0.0,0.0,1.0);
      }
   }
return;

More pictures: http://imgur.com/a/GQGpz

So it seems that this FXAA shader just does not work with Horde3D for some reason.

I attached the files to recreate my steps with the Chicago demo. Hopefully somebody in the know can help and tell me why this FXAA shader only works in horizontal direction and ignores the vertical.

Attachments:
File comment: Apply this Content folder to a clean Beta5 release of Horde3D to see the shader do its thing.
Content.zip [9.7 KiB]
Downloaded 1125 times

Author:  DarkAngel [ 20.01.2012, 12:15 ]
Post subject:  Re: FXAA

rand wrote:
I tried a few things, but in the end nothing worked out. I think it is my setup is still broken somehow. The problem is illustrated here:
......
Again you can see, the NorthSouth line is antialiased perfectly, but the EastWest line has weird pixel artifacts at the aliasing steps.
That's what FXAAv2 looks like...
It's a magic anti-aliasing filter that functions with only 5 texture lookups inside the 4x4 area around the current pixel (5 samples from a 16 pixel area!) -- with that amount of knowledge, it can't possibly do a good job on long almost-straight lines and you should expect artefacts!

Also, I'm not sure where your FXAA2 code came from, but mine doesn't match up with this Horde3D port. IIRC the texture filtering mode should be linear.
Instead of something like:
Code:
//vs
texCoords = vertPos.xy;
...
//fs
vec3 rgbNW=texture2D(buf0,texCoords+(vec2(-1.0,-1.0)/frameBufSize)).xyz;
vec3 rgbNE=texture2D(buf0,texCoords+(vec2(1.0,-1.0)/frameBufSize)).xyz;
vec3 rgbSW=texture2D(buf0,texCoords+(vec2(-1.0,1.0)/frameBufSize)).xyz;
vec3 rgbSE=texture2D(buf0,texCoords+(vec2(1.0,1.0)/frameBufSize)).xyz;
vec3 rgbM=texture2D(buf0,texCoords).xyz;
Mine looks something more like:
Code:
//vs
texCoords.xy = vertPos.xy;
texCoords.zw = vertPos.xy - ((0.5 + FXAA_SUBPIX_SHIFT) / frameBufSize);
...
//fs
vec3 rgbNW=texture2D(buf0,texCoords.zw).xyz;
vec3 rgbNE=texture2D(buf0,texCoords.zw+(vec2(1.0,0.0)/frameBufSize)).xyz;
vec3 rgbSW=texture2D(buf0,texCoords.zw+(vec2(0.0,1.0)/frameBufSize)).xyz;
vec3 rgbSE=texture2D(buf0,texCoords.zw+(vec2(1.0,1.0)/frameBufSize)).xyz;
vec3 rgbM=texture2D(buf0,texCoords.xy).xyz;


Also, if you do want better quality, FXAA2 has been replaced with FXAA3.x and FXAA4 by now :wink:

Author:  worstplayer [ 20.01.2012, 12:27 ]
Post subject:  Re: FXAA

Here's the odd part: I just tried your pipeline, and here's the result
Image
Works on my machineā„¢. I can't think of anything that could possibly cause it to only work horizontally on yours.

@DarkAngel: There's also this new technique, SMAA, that's supposed to be even better.

EDIT: tried adding FXAA_SUBPIX_SHIFT like in DarkAngel's code. If set to anything other than zero, vertical or horizontal edges stopped working, and with (1.0,1.0) it produced this pattern: Image Could this be what causes it?

Page 1 of 2 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/