Page 1 of 1

SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Thu Nov 18, 2010 4:00 am
by Tinnus
One of these days I found this technique that the author calls SSAA: http://gamestart3d.com/blog/ssaa-antialiasing and which, in turn, is based on an idea called NFAA: http://www.gamedev.net/community/forums ... _id=580517 . So basically what I did to get started learning a bit about the compositor system was to implement both of them as OGRE compositors (and also converted the SSAA shader to cg, which was pretty easy).

About the usefulness of both of them, just remember that they can be used in some places that "conventional" AA can't, especially deferred shading :)

The SSAA one is a bit faster for me and personally I think it looks better as well but that might just be due to bad parameter adjustments.

In any case, here are the screenshots, in order: without AA, SSAA and NFAA.

Image
Image
Image

Also, a close-up comparison of the barrel with SSAA:

Image

And now, the code for the SSAA compositor & material, pretty straightforward stuff (actually I copied most of it from the Tiling compositor :P ). They're identical for NFAA, just change the fragment program entry point.

Code: Select all

compositor SSAA
{
    technique
    {
        texture rt0 target_width target_height PF_A8R8G8B8

        target rt0
        {
            input previous
        }

        target_output
        {
            input none

            pass render_quad
            {
                material Ogre/Compositor/SSAA
                input 0 rt0
            }
        }
    }
}

Code: Select all

fragment_program Ogre/Compositor/SSAA_FP cg
{
	source SSAA_FP.cg
	entry_point SSAA_ps
	profiles ps_2_0 arbfp1
}

material Ogre/Compositor/SSAA
{
    technique
    {
		pass
		{
			cull_hardware none
			cull_software none
			depth_func always_pass

			vertex_program_ref Ogre/Compositor/StdQuad_Tex2a_vp
			{
			}

			fragment_program_ref Ogre/Compositor/SSAA_FP
			{
				param_named_auto ScreenSize inverse_texture_size 0
			}

			texture_unit source
			{
				tex_coord_set 0
				tex_address_mode clamp
				filtering trilinear
			}

		}
	}
}
And now the shaders code.

Code: Select all

float	lumRGB(float3 v)
{
	return dot(v, float3(0.212, 0.716, 0.072));
}

float4 SSAA_ps(float2 UV : TEXCOORD0,
               uniform float4 ScreenSize,
               sampler source : register(s0)) : COLOR
{
	float2    inverse_buffer_size = ScreenSize.xy;

	float   w = 1.75;

	float	t = lumRGB(tex2D(source, UV + float2(0.0, -1.0) * w * inverse_buffer_size).xyz),
		l = lumRGB(tex2D(source, UV + float2(-1.0, 0.0) * w * inverse_buffer_size).xyz),
		r = lumRGB(tex2D(source, UV + float2(1.0, 0.0) * w * inverse_buffer_size).xyz),
		b = lumRGB(tex2D(source, UV + float2(0.0, 1.0) * w * inverse_buffer_size).xyz);

	vec2    n = vec2(-(t - b), r - l);
	float   nl = length(n);

	if	(nl < (1.0 / 16.0))
		return tex2D(source, UV);
	else
	{
		n *= inverse_buffer_size / nl;

		float4	o = tex2D(source, UV),
			t0 = tex2D(source, UV + n * 0.5) * 0.9,
			t1 = tex2D(source, UV - n * 0.5) * 0.9,
			t2 = tex2D(source, UV + n) * 0.75,
			t3 = tex2D(source, UV - n) * 0.75;

		return (o + t0 + t1 + t2 + t3) / 4.3;
	}
}

float4 NFAA_ps(float2 UV : TEXCOORD0,
               uniform float4 ScreenSize,
	       sampler source : register(s0)) : COLOR
{ 
	float2 vPixelViewport = ScreenSize.xy;
	const float fScale = 1.75;

	// Offset coordinates
	float2 upOffset = float2( 0, vPixelViewport.y )* fScale;
	float2 rightOffset = float2( vPixelViewport.x, 0 ) * fScale;

	float topHeight =         lumRGB( tex2D( source, UV.xy + upOffset).rgb );
	float bottomHeight =      lumRGB( tex2D( source, UV.xy - upOffset).rgb );
	float rightHeight =       lumRGB( tex2D( source, UV.xy + rightOffset).rgb );
	float leftHeight =        lumRGB( tex2D( source, UV.xy - rightOffset).rgb );
	float leftTopHeight =     lumRGB( tex2D( source, UV.xy - rightOffset + upOffset).rgb );
	float leftBottomHeight =  lumRGB( tex2D( source, UV.xy - rightOffset - upOffset).rgb );
	float rightBottomHeight = lumRGB( tex2D( source, UV.xy + rightOffset + upOffset).rgb );
	float rightTopHeight =    lumRGB( tex2D( source, UV.xy + rightOffset - upOffset).rgb );
	  
	// Normal map creation
	float sum0 = rightTopHeight + topHeight + rightBottomHeight;
	float sum1 = leftTopHeight  + bottomHeight + leftBottomHeight;
	float sum2 = leftTopHeight  + leftHeight + rightTopHeight;
	float sum3 = leftBottomHeight + rightHeight + rightBottomHeight;

	float vec1 = (sum1 - sum0);
	float vec2 = (sum2 - sum3);

	// Put them together and scale.
	float2 Normal = float2( vec1, vec2) * vPixelViewport * fScale;

	// Color
	float4 Scene0 = tex2D( source, UV.xy );
	float4 Scene1 = tex2D( source, UV.xy + Normal.xy );
	float4 Scene2 = tex2D( source, UV.xy - Normal.xy );
	float4 Scene3 = tex2D( source, UV.xy + float2(Normal.x, -Normal.y) * 0.5 );
	float4 Scene4 = tex2D( source, UV.xy - float2(Normal.x, -Normal.y) * 0.5 );

	// Final color
	return (Scene0 + Scene1 + Scene2 + Scene3 + Scene4) * 0.2;
}

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Thu Nov 18, 2010 8:38 am
by boyamer
Nice effect, looks very nice,

Thanks for sharing.

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Thu Nov 18, 2010 4:35 pm
by tuan kuranes
Thanks for sharing.

You'll be interested in those links about MLAA ( Morphological Anti-Aliasing )
http://divergentcoder.com/rendering/mlaa-demo-2/
http://www.iryokufx.com/mlaa/

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Fri Nov 19, 2010 3:57 am
by mkultra333
I was just thinking about how to de-jaggy my deferred shading engine too. I was going to do some naive edge detection and blur of my own, but these sound much better. Thanks!

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Tue Jun 28, 2011 4:20 pm
by lordsme
Very interesting, I added it to our framework.
By the way, has anyone tried something more involved?
This techniques seems to fail when borders haven't enough color contrast.

Moreover, I had to manually update the screen size constant, changing it from auto to manual.

Thank you!

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Sun Sep 15, 2013 3:03 am
by nickG
Very interesting, I added it to our framework.
But how i can change of power?(4x,2x,1x,16x)

Re: SSAA (Screen Space Anti-Aliasing) and bonus: NFAA

Posted: Wed Sep 18, 2013 7:17 pm
by oiram
Great!!!