MOGRE Simple SSAO        

This is a MOGRE version of the Simple SSAO code.

The latest version of this code can be found here, but below is a backup copy in case that site goes down. (retrieved 21st feb 2012)

Table of contents

Converting to Mogre


Fortunately, the first 3 steps above stay exactly the same when converting this to Mogre. What we need to do is convert the PFXSSAO class from C++ to C# code. While we’re at it lets rename it to something more fitting.

public class SsaoManager : SceneManager.Listener
{
    private SceneManager _sceneManager;
    private Camera _camera;
    private Viewport _viewport;
    private RenderWindow _renderWindow;
    private CompositorInstance _compositor;
 
    public SsaoManager(RenderWindow renderWindow, Camera camera)
    {
        MaterialManager.Singleton.SetDefaultTextureFiltering(TextureFilterOptions.TFO_ANISOTROPIC);
 
        _renderWindow = renderWindow;
        _camera = camera;
        _sceneManager = camera.SceneManager;
        _viewport = camera.Viewport;
 
        InitialiseShadows();
        InitialiseSSAO();
    }
 
    private void InitialiseSSAO()
    {
        _compositor = CompositorManager.Singleton.AddCompositor(_viewport, "ssao");
        _compositor.Enabled = true;
        _compositor.NotifyMaterialRender += new CompositorInstance.Listener.NotifyMaterialRenderHandler(NotifyMaterialRender);
    }
 
    private void NotifyMaterialRender(uint passId, MaterialPtr material)
    {
        if (passId != 42)
            return;
 
        unsafe
        {
            Vector3 farCorner = _camera.GetViewMatrix(true) * _camera.WorldSpaceCorners[4];
            Pass pass = material.GetBestTechnique().GetPass(0);
            GpuProgramParametersSharedPtr parameters = pass.GetVertexProgramParameters();
 
            if (!parameters._findNamedConstantDefinition("farCorner").IsNull)
                parameters.SetNamedConstant("farCorner", farCorner);
 
            parameters = pass.GetFragmentProgramParameters();
 
            Matrix4 clipSpaceToImageSpace = new Matrix4(
                0.5f,    0,    0,  0.5f,
                0,   -0.5f,    0,  0.5f,
                0,      0,    1,    0,
                0,      0,    0,    1);
 
            if (!parameters._findNamedConstantDefinition("ptMat").IsNull)
                parameters.SetNamedConstant("ptMat", clipSpaceToImageSpace * _camera.ProjectionMatrixWithRSDepth);
 
            if (!parameters._findNamedConstantDefinition("far").IsNull)
                parameters.SetNamedConstant("far", _camera.FarClipDistance);
        }
    }
 
    public bool Enabled
    {
        get
        {
            return _compositor.Enabled;
        }
        set
        {
            _compositor.Enabled = value;
        }
    }
 
    private void InitialiseShadows()
    {
        _sceneManager.ShadowTextureSelfShadow = true;
        _sceneManager.SetShadowTextureCasterMaterial("shadow_caster");
        _sceneManager.ShadowTextureCount = 4;
 
        _sceneManager.SetShadowTextureSize(256);
        _sceneManager.SetShadowTexturePixelFormat(PixelFormat.PF_FLOAT16_RGB);
        _sceneManager.ShadowCasterRenderBackFaces = false;
 
        uint numShadowRTTs = _sceneManager.ShadowTextureCount;
        for (uint i = 0; i < numShadowRTTs; ++i)
        {
            TexturePtr texture = _sceneManager.GetShadowTexture(i);
            Viewport viewport = texture.GetBuffer().GetRenderTarget().GetViewport(0);
            viewport.BackgroundColour = new ColourValue(1, 1, 1, 1);
            viewport.SetClearEveryFrame(true);
        }
 
        _sceneManager.ShadowTechnique = ShadowTechnique.SHADOWTYPE_TEXTURE_ADDITIVE_INTEGRATED;
        _sceneManager.AddListener(this);
    }
 
    public override void ShadowTextureCasterPreViewProj(Light light, Camera camera, uint iteration)
    {
        float range = light.AttenuationRange;
        _camera.NearClipDistance = 0.01f;
        _camera.FarClipDistance = 99990f;
    }
}


Now all you have to do to start using SSAO in your Mogre project is create an instance of the SsaoManager like so (assuming you already have a RenderWindow and Camera):

SsaoManager ssaoManager = new SsaoManager(RenderWindow, Camera);