SMAA (Antialiasing technique) - image comparison added

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

If you haven't heard about SMAA (SMAA: Enhanced Subpixel Morphological Antialiasing), it is a new AA technique with very good results: http://www.iryoku.com/smaa/ - Make sure to download the HD movie for image comparison!

Because it's purely a post-processing technique, I figured it would be easy to integrate in Ogre and gave it a shot.

Here are the results (this is only SMAA1x, there are also SMAA T2x among others which should give much better results, but they are harder to integrate):

off
Image

on
Image


off
Image

on
Image

To enable it, simply add the SMAA compositor to your viewport and activate it.

smaa.material

Code: Select all

vertex_program SMAA/EdgeDetection_VS cg
{
    source smaa.cg
    profiles vs_4_0 vs_1_1 vp40 arbvp1
    entry_point EdgeDetection_VS
    default_params
    {
        param_named_auto viewportSize viewport_size
        param_named_auto wvp worldviewproj_matrix
    }
}

fragment_program SMAA/ColorEdgeDetection_PS cg
{
    source smaa.cg
    profiles ps_4_0 ps_2_x fp40 arbfp1
    entry_point ColorEdgeDetection_PS
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

fragment_program SMAA/LumaEdgeDetection_PS cg
{
    source smaa.cg
    profiles ps_4_0 ps_2_x fp40 arbfp1
    entry_point LumaEdgeDetection_PS
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

fragment_program SMAA/DepthEdgeDetection_PS cg
{
    source smaa.cg
    profiles ps_4_0 ps_2_x fp40 arbfp1
    entry_point DepthEdgeDetection_PS
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

vertex_program SMAA/BlendWeightCalculation_VS cg
{
    source smaa.cg
    profiles vs_4_0 vs_1_1 vp40 arbvp1
    entry_point BlendWeightCalculation_VS
    default_params
    {
        param_named_auto viewportSize viewport_size
        param_named_auto wvp worldviewproj_matrix
    }
}

fragment_program SMAA/BlendWeightCalculation_PS cg
{
    source smaa.cg
    profiles ps_4_0 ps_2_x fp40 arbfp1 
    entry_point BlendWeightCalculation_PS
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

vertex_program SMAA/NeighborhoodBlending_VS cg
{
    source smaa.cg
    profiles vs_4_0 vs_1_1 vp40 arbvp1
    entry_point NeighborhoodBlending_VS
    default_params
    {
        param_named_auto viewportSize viewport_size
        param_named_auto wvp worldviewproj_matrix
    }
}

fragment_program SMAA/NeighborhoodBlending_PS cg
{
    source smaa.cg
    profiles ps_4_0 ps_2_x fp40 arbfp1 
    entry_point NeighborhoodBlending_PS
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

material SMAA/ColorEdgeDetection
{
    technique
    {
        pass
        {
            vertex_program_ref SMAA/EdgeDetection_VS
            {
            }

            fragment_program_ref SMAA/ColorEdgeDetection_PS
            {
            }

            depth_check off

            texture_unit colorGammaTex
            {
                tex_address_mode clamp
                filtering linear linear linear
            }

            texture_unit predicationTex
            {
				tex_address_mode clamp
				filtering linear linear linear
            }
        }
    }
}

material SMAA/LumaEdgeDetection
{
    technique
    {
        pass
        {
            vertex_program_ref SMAA/EdgeDetection_VS
            {
            }

            fragment_program_ref SMAA/LumaEdgeDetection_PS
            {
            }

            depth_check off

            texture_unit colorGammaTex
            {
                tex_address_mode clamp
                filtering linear linear linear
            }

            texture_unit predicationTex
            {
				tex_address_mode clamp
				filtering linear linear linear
            }
        }
    }
}

material SMAA/DepthEdgeDetection
{
    technique
    {
        pass
        {
            vertex_program_ref SMAA/EdgeDetection_VS
            {
            }

            fragment_program_ref SMAA/LumaEdgeDetection_PS
            {
            }

            depth_check off

            texture_unit depthTex
            {
                tex_address_mode clamp
                filtering linear linear linear
            }
        }
    }
}

material SMAA/BlendWeightCalculation
{
    technique
    {
        pass
        {
            vertex_program_ref SMAA/BlendWeightCalculation_VS
            {
            }

            fragment_program_ref SMAA/BlendWeightCalculation_PS
            {
            }

            depth_check off

            texture_unit edgesTex
            {
                tex_address_mode clamp
                filtering linear linear linear
            }

            texture_unit areaTex
            {
                texture AreaTexDX10.dds
                tex_address_mode clamp
                filtering linear linear linear
            }

            texture_unit searchTex
            {
                texture SearchTex.dds
                tex_address_mode clamp
                filtering point point point
            }
        }
    }
}

material SMAA/NeighborhoodBlending
{
    technique
    {
        pass
        {
            vertex_program_ref SMAA/NeighborhoodBlending_VS
            {
            }

            fragment_program_ref SMAA/NeighborhoodBlending_PS
            {
            }

            depth_check off

            texture_unit colorTex
            {
                tex_address_mode clamp
                filtering linear linear point
            }
            texture_unit blendTex
            {
                tex_address_mode clamp
                filtering linear linear linear
            }
        }
    }
}
SMAA.compositor

Code: Select all

compositor SMAA
{
    technique
    {
        texture previousscene target_width target_height PF_A8R8G8B8
        texture edgeTex target_width target_height PF_FLOAT16_RGBA
        texture blendTex target_width target_height PF_FLOAT16_RGBA

        target previousscene
        {
            input previous
        }

        // Edge detection pass
        target edgeTex
        {
            input none

            pass clear
            {
            }
            pass stencil
            {
                check on
                ref_value 1
                pass_op replace
            }
            pass render_quad
            {
                material SMAA/ColorEdgeDetection
                input 0 previousscene
            }
        }

        // Blending weights calculation pass
        target blendTex
        {
            input none

            pass clear
            {
            }
            pass stencil
            {
                // Process only marked pixels
                check on
                pass_op keep
                comp_func equal
                ref_value 1
            }
            pass render_quad
            {
                material SMAA/BlendWeightCalculation
                input 0 edgeTex
            }
        }

        // Neighborhood blending pass
        target_output
        {
            input none

            pass stencil
            {
                // Process _all_ pixels
                check off
            }
            pass render_quad
            {
                material SMAA/NeighborhoodBlending
                input 0 previousscene
                input 1 blendTex
            }
        }
    }
}

smaa.cg

Code: Select all

#define SMAA_PRESET_HIGH 1
//#define SMAA_PREDICATION 1
#define SMAA_CG 1

#include "SMAA.h"

void EdgeDetection_VS(in float4 position : POSITION,
                        out float4 oPosition : POSITION,
                        uniform float4x4 wvp,
                             inout float2 texcoord : TEXCOORD0,
                             out float4 offset[3] : TEXCOORD1,
                             uniform float4 viewportSize
                             ) {
    position.xy = sign(position.xy);

    texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;

    SMAAEdgeDetectionVS(position, oPosition, texcoord, offset, viewportSize.zw);

    oPosition = mul(wvp, position);
}

void BlendWeightCalculation_VS(in float4 position : POSITION,
                        out float4 oPosition : POSITION,
                        uniform float4x4 wvp,
                                         inout float2 texcoord : TEXCOORD0,
                                         out float2 pixcoord : TEXCOORD1,
                                         out float4 offset[3] : TEXCOORD2,
                                         uniform float4 viewportSize
                                         ) {
    position.xy = sign(position.xy);

    texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;

    SMAABlendingWeightCalculationVS(position, oPosition, texcoord, pixcoord, offset, viewportSize.zw);
    oPosition = mul(wvp, position);
}

void NeighborhoodBlending_VS(in float4 position : POSITION,
                        out float4 oPosition : POSITION,
                        uniform float4x4 wvp,
                                    inout float2 texcoord : TEXCOORD0,
                                    out float4 offset[2] : TEXCOORD1,
                                    uniform float4 viewportSize
                                    ) {
    position.xy = sign(position.xy);

    texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;

    SMAANeighborhoodBlendingVS(position, oPosition, texcoord, offset, viewportSize.zw);
    oPosition = mul(wvp, position);
}


float4 LumaEdgeDetection_PS(float4 position : POSITION,
                                   float2 texcoord : TEXCOORD0,
                                   float4 offset[3] : TEXCOORD1,
									#if SMAA_PREDICATION == 1
									SMAATexture2D predicationTex : TEXUNIT1,
									#endif
                                   uniform SMAATexture2D colorGammaTex : TEXUNIT0,
                                   uniform float4 viewportSize
                                   ) : COLOR {
    //return SMAALumaEdgeDetectionPS(texcoord, offset, colorGammaTex, predicationTex);
    return SMAALumaEdgeDetectionPS(texcoord, offset, colorGammaTex, viewportSize.zw);
}

float4 ColorEdgeDetection_PS(float4 position : POSITION,
                                    float2 texcoord : TEXCOORD0,
                                    float4 offset[3] : TEXCOORD1,
                                    uniform float4 viewportSize,
									#if SMAA_PREDICATION == 1
									SMAATexture2D predicationTex : TEXUNIT1,
									#endif
                                    uniform SMAATexture2D colorGammaTex : TEXUNIT0) : COLOR {
    //return SMAAColorEdgeDetectionPS(texcoord, offset, colorGammaTex, predicationTex);
    return SMAAColorEdgeDetectionPS(texcoord, offset, colorGammaTex, viewportSize.zw);
}

float4 DepthEdgeDetection_PS(float4 position : POSITION,
                                    float2 texcoord : TEXCOORD0,
                                    float4 offset[3] : TEXCOORD1,
                                    uniform float4 viewportSize,
                                    uniform SMAATexture2D depthTex : TEXUNIT0) : COLOR {
    return SMAADepthEdgeDetectionPS(texcoord, offset, depthTex, viewportSize.zw);
}

float4 BlendWeightCalculation_PS(float4 position : POSITION,
                                           float2 texcoord : TEXCOORD0,
                                           float2 pixcoord : TEXCOORD1,
                                           float4 offset[3] : TEXCOORD2,
                                           uniform float4 viewportSize,
                                           uniform SMAATexture2D edgesTex : TEXUNIT0, 
                                           uniform SMAATexture2D areaTex : TEXUNIT1, 
                                           uniform SMAATexture2D searchTex : TEXUNIT2) : COLOR {
    return SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, edgesTex, areaTex, searchTex, viewportSize.zw, 0);
}

float4 NeighborhoodBlending_PS(float4 position : POSITION,
                                      float2 texcoord : TEXCOORD0,
                                      float4 offset[2] : TEXCOORD1,
                                      uniform float4 viewportSize,
                                      uniform SMAATexture2D colorTex : TEXUNIT0,
                                      uniform SMAATexture2D blendTex : TEXUNIT1) : COLOR {
    return SMAANeighborhoodBlendingPS(texcoord, offset, colorTex, blendTex, viewportSize.zw);
}
SMAA.h (this goes in the same folder as smaa.cg, it is mostly copy&paste from their demo)
Download here: https://github.com/scrawl/smaa/raw/master/SMAA.h

Then, download these 2 precomputed textures and put them in your resource path:

https://github.com/iryoku/smaa/raw/mast ... exDX10.dds
https://github.com/iryoku/smaa/raw/mast ... rchTex.dds
Last edited by scrawl on Thu May 31, 2012 3:58 pm, edited 4 times in total.
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

I managed to get much better results by using PF_FLOAT16_RGBA textures in the compositor. (Don't ask me why) I think for a very cheap compositor it looks very good already, much better than the SSAA/NFAA somewhere here on the forum.

Right now I'm trying to figure out SMAA T2x (temporal supersampling)
al2950
OGRE Expert User
OGRE Expert User
Posts: 1227
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 157

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by al2950 »

Looks very interesting. Have not tried your code yet but will have a look after you get T2x working :) . I love the face Ogre has a number of Crytek techniques available to use. We just need RLR and a GI!
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

al2950 wrote:Looks very interesting. Have not tried your code yet but will have a look after you get T2x working :) . I love the face Ogre has a number of Crytek techniques available to use. We just need RLR and a GI!
Thanks :) Well.. I like to say that (almost) anything is possible in Ogre, as long as you can write shaders for it :D Really, the only thing holding us back is the rendersystems - I really hope GL4 will be available soon with tesselation.

No SMAA news right now, sorry. I'm just too busy to implement T2x right now. It's definitely possible, though it will be harder to integrate in existing ogre projects because of the needed shader changes (subpixel jitters and velocity textures). Thus I'm afraid it will be of limited use compared to the standard SMAA1x which is just a matter of calling addCompositor.
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by Ertyui »

Is this only possbile with DirectX10 or higher?
Because I first got tex2Dlod errors, which I fixed by manually adding the method.
And then I got this error:

Code: Select all

SMAA.h(992) : error C5011: profile does not support "while" statements and "while" could not be unrolled.
I think it's because of the vertex shader profile, but I'm not sure.
I also get several errors about terms used in the compositor:

Code: Select all

21:20:20: Compiler error: unknown error in smaa.compositor(47): token "pass_op" is not recognized
21:20:20: Compiler error: unknown error in smaa.compositor(48): token "comp_func" is not recognized
21:20:20: Compiler error: unknown error in smaa.compositor(49): token "ref_value" is not recognized
21:20:20: Compiler error: unknown error in smaa.compositor(66): token "check" is not recognized
Thanks in advance,

Greetz Ertyui
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

About the first error: It will definitely run in DirectX9 (it does in the demo where I got it from), but there it uses HLSL and not CG like I did here. So to fix that, you could define the SMAA_HLSL var instead of SMAA_CG and use "hlsl" and not "cg" in the shader languages (smaa.material)
You could also simply try to use ps_3_0 profile which should definitely have tex2lod.

About the second error: I have used Ogre 1.8 trunk, there was a syntax change since 1.7. To run on 1.7 you have to change everything in smaa.compositor from this:

Code: Select all

pass clear
{
   ......
}
to this:

Code: Select all

pass clear
{
  clear
  {
   ......
  }
}
the same with pass stencil { and so on.
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by Ertyui »

Thanks for your answer.
I also use Ogre 1.8, so I don't know why it wouldn't work, I'll look into that.
I'll try the ps_3 format tomorrow, thanks for the help so far :)
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

The syntax change was between 1.8RC1 and 1.8 final, so make sure to use either 1.8 final or trunk. RC1 will not work.
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by Ertyui »

Ah, I was indeed still working with RC. I've switched to Ogre 1.8 stable which indeed fixed the compositor errors.
I've also fixed the tex2DLod error by adding the ps_3_0 and vs_3_0 profiles to the programs.

But it still doesn't work.
The game runs but when I enable the compositor instance the screen freezes and get's lighter. I can still move around, but I won't see it. After disabling the compositor I can see where I should've been again.
So there's still something wrong. I can't use shadermodel 4 because my graphics card doesn't support it.

I don't get any additional errors, so I'm wondering what goes wrong.
Do you have suggestions where I should look at? I can also make a little video if you want to.

Thanks for the help,

Greetz Ertyui

Edit:
Nvm it works now :) I probably missed to define a profile I guess. I can see now that the edges are getting blurred, but I don't think it's working properly yet. I think that maybe the whole scene is blurred..
Last edited by Ertyui on Tue May 29, 2012 3:10 pm, edited 1 time in total.
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

could you paste the ogre log just in case?

if the whole screen freezes, then it sounds like a compositor / ogre issue and not shader problem.

it would be also helpful to see the content of the compositor textures. here's an example code you can use to display them

Code: Select all

	OverlayManager& mgr = OverlayManager::getSingleton();
	Overlay* overlay;
	// destroy if already exists
	if (overlay = mgr.getByName("DebugOverlay"))
		mgr.destroy(overlay);
	overlay = mgr.create("DebugOverlay");
	Ogre::CompositorInstance  *compositor= CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("SMAA");
	for (int i=0; i<2; ++i)
	{
		// Set up a debug panel
		if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + toStr(i)))
			MaterialManager::getSingleton().remove("Ogre/DebugTexture" + toStr(i));
		MaterialPtr debugMat = MaterialManager::getSingleton().create(
			"Ogre/DebugTexture" + toStr(i), 
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
		TexturePtr depthTexture = compositor->getTextureInstance(i == 0 ? "edgeTex" : "blendTex",0);
		if(!depthTexture.isNull())
		{
			TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(depthTexture->getName());
			t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
		}
		OverlayContainer* debugPanel;
		// destroy container if exists
		try
		{
			if (debugPanel = 
				static_cast<OverlayContainer*>(
					mgr.getOverlayElement("Ogre/DebugTexPanel" + toStr(i)
				)))
				mgr.destroyOverlayElement(debugPanel);
		}
		catch (Ogre::Exception&) {}
		debugPanel = (OverlayContainer*)
			(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
		debugPanel->_setPosition(0.67, i*0.33);
		debugPanel->_setDimensions(0.33, 0.33);
		debugPanel->setMaterialName(debugMat->getName());
		debugPanel->show();
		overlay->add2D(debugPanel);
		overlay->show();
	}

scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

I can see now that the edges are getting blurred, but I don't think it's working properly yet. I think that maybe the whole scene is blurred..
Hm, for me only the edges are blurred. Can I see the compositor texture contents? (see my previous post)
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by Ertyui »

Hey sorry for the late response and thanks for the help so far.
I had some problems with the Ogre 1.8 stable build, it won't compile anymore, so I switched to the RC again while using the stable dlls (but I opened a different thread about that).
Anyway I got two screenshot with the compositor contents, one without and one with SMAA.

I think you where right about only blurring the edges indeed, but I'm not sure if this is the effect as it should be. Oh and I an error while running the application but I can continue and it runs just fine. This is the error:

Code: Select all

Run-Time Check Failure #2 - Stack around the variable 'depthTexture' was corrupted.
Edit:
I forgot to alter the resolution in the smaa.cg :S, so I updated the images :)
Attachments
Screenshot without SMAA
Screenshot without SMAA
withoutSMAA.jpg (173.72 KiB) Viewed 12354 times
Screenshot with SMAA
Screenshot with SMAA
withSMAA.jpg (163.17 KiB) Viewed 12354 times
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA in Ogre, almost there (Antialiasing technique)

Post by scrawl »

Your scene doesn't really have much contrast, so SMAA probably has a few difficulties. I've noticed myself that it works best for near-vertical (or horizontal) high-contrast edges. (Which is good, because those are the most noticable anyway)

Here's mine:

off
Image

on
Image


off
Image

on
Image
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

Updated the shader, now the viewport size is set automatically! Make sure to re-download SMAA.h as well.
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

Hmm, it looks way better in your second example than in my example. This was just a test scene, my normal scene has more contrast difference. But it doesn't show the same result as yours either.
Here are two samples from that one:
Attachments
diffSceneWithoutSMAA.jpg
diffSceneWithoutSMAA.jpg (56.57 KiB) Viewed 12335 times
diffSceneWithSMAA.jpg
diffSceneWithSMAA.jpg (50.9 KiB) Viewed 12335 times
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

I'm not sure if the blending weights pass is working correctly for you. If it did, then there should be subtle lines visible on the second panel. (But maybe it's just the JPG compression that I don't see them). Like on this picture: http://scrawl.bplaced.net/perm/675.png
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

Oh, I've seen the subtile lines and after the screenshot they're less visible, so I guess it's because of the jpeg compression..
User avatar
duststorm
Minaton
Posts: 921
Joined: Sat Jul 31, 2010 6:29 pm
Location: Belgium
x 80
Contact:

Re: SMAA (Antialiasing technique) - image comparison added

Post by duststorm »

Ertyui wrote:I guess it's because of the jpeg compression..
Maybe it's a good idea to post comparison shots where details really matter in png format, it's lossless.
Developer @ MakeHuman.org
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

duststorm wrote:
Ertyui wrote:I guess it's because of the jpeg compression..
Maybe it's a good idea to post comparison shots where details really matter in png format, it's lossless.
Yeah I had it configured by standard to save the screenshots as .jpg's :P. I'll make them again..
Last edited by Ertyui on Fri Jun 01, 2012 1:10 am, edited 1 time in total.
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

Here are png versions of the screenshots.
Attachments
diffSceneWithoutSMAA.png
diffSceneWithoutSMAA.png (215.06 KiB) Viewed 12307 times
diffSceneWithSMAA.png
diffSceneWithSMAA.png (239.23 KiB) Viewed 12307 times
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

After looking at screenshots of the SMAA demo (I can't run it myself) it really looks much better than what is here. Not sure where the mistake is. You said that you were using Direct3d (opengl here), so it's probably not because of the difference in opengl/direct3d. In the meantime here is nvidia's FXAA which works better (though it does have a problem with blurring some distant things too much)


fxaa.cg

Code: Select all



/*---------------------------------------------------------*/
    #define FXAA_REDUCE_MIN   (1.0/128.0)
    #define FXAA_REDUCE_MUL   (1.0/8.0)
    #define FXAA_SPAN_MAX     8.0
	#define FXAA_SUBPIX_SHIFT 1.0/4.0

/*---------------------------------------------------------*/


void main_vp
(
	uniform float4x4 wvp,
	in float4 iPosition : POSITION,
	out float4 oPosition : POSITION,
	uniform float4 viewportSize,
	out float4 oPosPos : TEXCOORD1 // texcoord adjusted with subpixel offset
)
{
	float2 rcpFrame = float2(viewportSize.z, viewportSize.w);

    iPosition.xy = sign(iPosition.xy);

    float2 texcoord = (float2(iPosition.x, -iPosition.y) + 1.0f) * 0.5f;

	oPosPos = float4(texcoord, texcoord - (rcpFrame * (0.5 + FXAA_SUBPIX_SHIFT)));

    oPosition = mul(wvp, iPosition);
}

void main_fp
(
	uniform float4 viewportSize,
	uniform sampler2D colorTex : TEXUNIT0,
	in float4 iPosPos : TEXCOORD1,
	out float4 oColor : COLOR
)
{
	float4 posPos = iPosPos;

	float2 rcpFrame = float2(viewportSize.z, viewportSize.w);

    float3 rgbNW = tex2Dlod(colorTex, float4(posPos.zw, 0, 0)).xyz;
    float3 rgbNE = tex2Dlod(colorTex, float4(posPos.zw + float2(1.0,0.0)*rcpFrame.xy, 0.0, 0)).xyz;
    float3 rgbSW = tex2Dlod(colorTex, float4(posPos.zw + float2(0.0,1.0)*rcpFrame.xy, 0.0, 0)).xyz;
    float3 rgbSE = tex2Dlod(colorTex, float4(posPos.zw + float2(1.0,1.0)*rcpFrame.xy, 0.0, 0)).xyz;
    float3 rgbM  = tex2Dlod(colorTex, float4(posPos.xy,0.0,0)).xyz;

    float3 luma = float3(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)));

    float2 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(float2( FXAA_SPAN_MAX,  FXAA_SPAN_MAX),
          max(float2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
          dir * rcpDirMin)) * rcpFrame.xy;

    float3 rgbA = (1.0/2.0) * (
        tex2Dlod(colorTex, float4(posPos.xy + dir * (1.0/3.0 - 0.5),0.0, 0)).xyz +
        tex2Dlod(colorTex, float4(posPos.xy + dir * (2.0/3.0 - 0.5),0.0, 0)).xyz);
    float3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (
        tex2Dlod(colorTex, float4(posPos.xy + dir * (0.0/3.0 - 0.5),0.0, 0)).xyz +
        tex2Dlod(colorTex, float4(posPos.xy + dir * (3.0/3.0 - 0.5),0.0, 0)).xyz);
    float lumaB = dot(rgbB, luma);
    if((lumaB < lumaMin) || (lumaB > lumaMax))
		oColor = float4(rgbA, 1.0);
    else
		oColor = float4(rgbB, 1.0);
}
fxaa.compositor

Code: Select all

compositor FXAA
{
    technique
    {
        texture previousscene target_width target_height PF_A8R8G8B8

        target previousscene
        {
            input previous
        }

        target_output
        {
            input none

            pass render_quad
            {
                material FXAA
                input 0 previousscene
            }
        }
	}
}
fxaa.material

Code: Select all

vertex_program FXAA/Vertex cg
{
    source fxaa.cg
    profiles vs_4_0 vs_1_1 vp40 arbvp1
    entry_point main_vp
    default_params
    {
        param_named_auto viewportSize viewport_size
        param_named_auto wvp worldviewproj_matrix
    }
}

fragment_program FXAA/Pixel cg
{
    source fxaa.cg

	// needs PS3 for tex2Dlod
    profiles ps_4_0 ps_3_0 fp40

    entry_point main_fp
    default_params
    {
        param_named_auto viewportSize viewport_size
    }
}

material FXAA
{
	technique
	{
		pass
		{
			vertex_program_ref FXAA/Vertex
			{
			}
			fragment_program_ref FXAA/Pixel
			{
			}

			depth_check off

			texture_unit
			{
				tex_address_mode clamp
				filtering linear linear point
			}
		}
	}
}
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

SMAA news!

I had a nice chat with Yours3lf who also had trouble getting SMAA to work, in his case for OpenGL/SFML. He contacted the SMAA author a while ago and finally got a reply that allowed him to fix his implementation. I've uploaded his stand-alone demo here for convenience: https://github.com/scrawl/smaa-opengl

The problems were: 1. the search/area textures were not loaded correctly. 2. GL_FRAMEBUFFER_SRGB had to be enabled in the last pass. 3. a shader change was needed because of the right-handed coordinate system Ogre/OpenGL uses.

This information should allow me to fix the Ogre SMAA implementation. I will probably make a new thread with a standalone demo once I'm done, so stay tuned :)
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

Awesome!! I'm looking forward to it. I've finished my last project and I'm now working on a new one. First I'm focusing on the level design pipeline (blender2ogre with my own parser for physics and game logics, I will probably post about it sometime later) and gameplay. And about half November I'm going to focus on the graphical part, so I might be able to use it then.

Great work :D
scrawl
OGRE Expert User
OGRE Expert User
Posts: 1119
Joined: Sat Jan 01, 2011 7:57 pm
x 216

Re: SMAA (Antialiasing technique) - image comparison added

Post by scrawl »

Sorry to disappoint you but I've stopped working on it because I simply couldn't figure out what else was wrong. But if someone wants to give it a try here is the current source: https://github.com/scrawl/smaa-ogre
Ertyui
Gnoblar
Posts: 15
Joined: Tue Jan 10, 2012 7:24 pm

Re: SMAA (Antialiasing technique) - image comparison added

Post by Ertyui »

No problem :) Thanks for the source :D
Post Reply