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.
Copy to clipboard
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):
Copy to clipboard
SsaoManager ssaoManager = new SsaoManager(RenderWindow, Camera);