SSAO Problem

Jo0oker

31-05-2011 18:06:21

Dear Mogre user,
i have ported this SSAO-Code:
http://www.ogre3d.org/forums/viewtopic.php?t=42350
to C# and Mogre. It compiles, but doesn't work. It only makes everything confusing.

This are the main classes:
QuadRenderer:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;

namespace Tehadon.Gfx.TEffect
{
public unsafe class QuadRenderer
{
#region Private Member

private ManualObject myQuad;
private Camera myCamera;

#endregion

#region Konstruktor
public QuadRenderer(Camera Cam)
{
//Create the Quad
myCamera = Cam;
myQuad = myCamera.SceneManager.CreateManualObject("QuadRenderer:quad");

Vector3* Corners = myCamera.WorldSpaceCorners;

myQuad.Begin("Chuck Norris", RenderOperation.OperationTypes.OT_TRIANGLE_LIST);
{
// top-left
myQuad.Position(new Vector3(-1, 1, 0));
myQuad.Normal(Corners[5]);
myQuad.TextureCoord(new Vector2(0, 0));

// bottom-left
myQuad.Position(new Vector3(-1, -1, 0));
myQuad.Normal(Corners[6]);
myQuad.TextureCoord(new Vector2(0, 1));

// bottom-right
myQuad.Position(new Vector3(1, -1, 0));
myQuad.Normal(Corners[7]);
myQuad.TextureCoord(new Vector2(1, 1));

// top-right
myQuad.Position(new Vector3(1, 1, 0));
myQuad.Normal(Corners[4]);
myQuad.TextureCoord(new Vector2(1, 0));

// we put the vertices in anti-clockwise,
// so just start at 0 and go to 3
myQuad.Quad(0, 1, 2, 3);
}
myQuad.End();
}
#endregion

#region Go
/// <summary>
/// Go
/// </summary>
/// <param name="Pass">Pass</param>
/// <param name="ViewPort">Viewport</param>
public void Go(Pass Pass, Viewport ViewPort)
{
RenderSystem cRS = Root.Singleton.RenderSystem;
SceneManager cSceneManager;
RenderOperation cROp = new RenderOperation();

myQuad.GetSection(0).GetRenderOperation(cROp);

cRS._beginFrame();
cRS._setViewport(ViewPort);

cSceneManager = myQuad._getManager();

cSceneManager._setPass(Pass, true, false);
if (Pass.HasVertexProgram)
cRS.BindGpuProgramParameters(
GpuProgramType.GPT_VERTEX_PROGRAM, Pass.GetVertexProgramParameters(), 0); //Not sure, if it works
else
cRS.UnbindGpuProgram(GpuProgramType.GPT_VERTEX_PROGRAM);
if (Pass.HasFragmentProgram)
cRS.BindGpuProgramParameters(
GpuProgramType.GPT_FRAGMENT_PROGRAM, Pass.GetFragmentProgramParameters(), 0); //Not sure, if it works
else
cRS.UnbindGpuProgram(GpuProgramType.GPT_FRAGMENT_PROGRAM);

cRS._setWorldMatrix(Matrix4.IDENTITY);
cRS._setViewMatrix(Matrix4.IDENTITY);
cRS._setProjectionMatrix(Matrix4.IDENTITY);

cRS._render(cROp);

cRS._endFrame();
}
#endregion

#region Public Member
public ManualObject Quad
{
get { return myQuad; }
set { myQuad = value; }
}

public Camera Camera
{
get { return myCamera; }
set { myCamera = value; }
}
#endregion
}
}



SSEffect:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;

namespace Tehadon.Gfx.TEffect
{
public class ProjectionMatrix
{
#region Constants
public static Matrix4 PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE = new Matrix4(
0.5f, 0, 0, 0.5f,
0, -0.5f, 0, 0.5f,
0, 0, 1, 0,
0, 0, 0, 1);
#endregion
}

public class SSEffect
{
#region Private Member
private Camera myCamera;
private Viewport myViewPort;
private Texture myTexture;
private bool myTexIsExtern;
private RenderTarget myRenderTarget;

private Pass myPass;

private bool myEnabled;
private string myName;

private QuadRenderer myQuadRenderer;
#endregion

#region Construktor
/// <summary>
/// Constructor
/// </summary>
/// <param name="Name"></param>
/// <param name="QuadRenderer"></param>
public SSEffect(string Name, QuadRenderer QuadRenderer)
{
myName = Name;
myQuadRenderer = QuadRenderer;
myEnabled = true;
myTexIsExtern = false;
}
#endregion

#region Create
/// <summary>
/// Create the SSEffect and a new Rendertexture
/// </summary>
/// <param name="Weidht"></param>
/// <param name="Height"></param>
/// <param name="PixelFormat"></param>
public void Create(uint Weidht, uint Height, PixelFormat PixelFormat)
{
Destroy();

TexturePtr cMidPtr = TextureManager.Singleton.CreateManual(
myName + "_tex", "Internal", TextureType.TEX_TYPE_2D, Weidht, Height, 0, PixelFormat, 512); //512 = TU_RENDERTARGET

myTexture = cMidPtr;
myTexIsExtern = false;

myRenderTarget = myTexture.GetBuffer(0).GetRenderTarget(0);
myRenderTarget.IsAutoUpdated = (false);

myCamera = myQuadRenderer.Camera.SceneManager.CreateCamera(myName + "_cam");
myViewPort = myRenderTarget.AddViewport(myCamera, myRenderTarget.NumViewports);
myViewPort.BackgroundColour = (ColourValue.White);
myViewPort.SetClearEveryFrame(false);
myViewPort.ShadowsEnabled = (false);
myViewPort.OverlaysEnabled = (false);

myCamera.AspectRatio = ((float)(Weidht / (float)Height));
myCamera.FOVy = (new Degree(90));
}

/// <summary>
/// Create the SSEffect with an existing Rendertexture
/// </summary>
/// <param name="RenderTexture"></param>
public void Create(Texture RenderTexture)
{
Destroy();

myTexture = RenderTexture;
myTexIsExtern = true;
myRenderTarget = myTexture.GetBuffer(0).GetRenderTarget(0);

myViewPort = myRenderTarget.GetViewport(0);
myCamera = myViewPort.Camera;
}
#endregion

#region Destroy
/// <summary>
/// Destroy the SSEffect
/// </summary>
public void Destroy()
{
if (!myTexIsExtern)
{
if (myTexture != null)
{
TextureManager.Singleton.Remove(myTexture.Name);
}
if (myCamera != null)
{
myCamera.SceneManager.DestroyCamera(myCamera);
}

myTexture = null;
myCamera = null;
myRenderTarget = null;
myViewPort = null;
}
}
#endregion

#region Update
/// <summary>
/// Update the SSEffect
/// </summary>
public void Update()
{
if (!myEnabled || myPass == null)
{
return;
}

//Update
myQuadRenderer.Go(myPass, myViewPort);
}
#endregion

#region Clear
/// <summary>
/// Clear the SSEffect
/// </summary>
public void Clear()
{
RenderSystem cRenderSystem = Root.Singleton.RenderSystem;
cRenderSystem._setViewport(myViewPort);
cRenderSystem.ClearFrameBuffer(
1 | 2 | 4, //-> Mogre.FrameBufferType.FBT_COLOUR | FrameBufferType.FBT_DEPTH | FrameBufferType.FBT_STENCIL
myViewPort.BackgroundColour);
}
#endregion

#region Public Member
public Camera Camera
{
get { return myCamera; }
set { myCamera = value; }
}

public Viewport ViewPort
{
get { return myViewPort; }
set { myViewPort = value; }
}

public bool TexIsExtern
{
get { return myTexIsExtern; }
set { myTexIsExtern = value; }
}

public RenderTarget RenderTarget
{
get { return myRenderTarget; }
set { myRenderTarget = value; }
}

public Texture Texture
{
get { return myTexture; }
set { myTexture = value; }
}

public Pass Pass
{
get { return myPass; }
set { myPass = value; }
}

public bool Enabled
{
get { return myEnabled; }
set { myEnabled = value; }
}

public QuadRenderer QuadRenderer
{
get { return myQuadRenderer; }
set { myQuadRenderer = value; }
}
#endregion
}
}


SSAO

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;

namespace Tehadon.Gfx.TEffect
{
public class SSAO : SSEffect
{
#region Private Member

#endregion

#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="Name"></param>
/// <param name="QuadRenderer"></param>
public SSAO(string Name, QuadRenderer QuadRenderer)
: base(Name, QuadRenderer)
{
MaterialPtr cMidPtr = MaterialManager.Singleton.Load("ssao", "Internal");
base.Pass = cMidPtr.GetBestTechnique().GetPass(0);
base.Pass.GetTextureUnitState(0).SetTextureName("geom_tex");
base.Pass._load();
}
#endregion

#region Create
/// <summary>
/// Create the SSAO
/// </summary>
/// <param name="Texture"></param>
private void Create(Texture Texture)
{

}

/// <summary>
/// Create the SSAO
/// </summary>
/// <param name="Weidth"></param>
/// <param name="Height"></param>
/// <param name="PixelFormat"></param>
public void Create(uint Weidth, uint Height, PixelFormat PixelFormat = PixelFormat.PF_R8G8B8)
{
base.Create(Weidth, Height, PixelFormat);
}
#endregion

#region Update
/// <summary>
/// Update SSAO
/// </summary>
public void Update()
{
if (!Enabled || base.Pass == null)
{
return;
}

GpuProgramParametersSharedPtr cParams = base.Pass.GetFragmentProgramParameters();

if (!cParams._findNamedConstantDefinition("pMat").IsNull)
{
cParams.SetNamedConstant(
"pMat",
ProjectionMatrix.PROJECTIONCLIPSPACE2DTOIMAGESPACE_PERSPECTIVE *
base.QuadRenderer.Camera.ProjectionMatrixWithRSDepth);
}

if (!cParams._findNamedConstantDefinition("far").IsNull)
{
cParams.SetNamedConstant("far", base.QuadRenderer.Camera.FarClipDistance);
}

base.Update();
}
#endregion

#region Public Member

#endregion
}
}



Geom

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mogre;

namespace Tehadon.Gfx.TEffect
{
public class Geom : SSEffect
{
#region Private Member

#endregion

#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="Name"></param>
/// <param name="QuadRenderer"></param>
public Geom(string Name, QuadRenderer QuadRenderer)
: base(Name, QuadRenderer)
{

}
#endregion

#region Create
/// <summary>
/// Create the SSAO
/// </summary>
/// <param name="Texture"></param>
private void Create(Texture Texture)
{

}

/// <summary>
/// Create the SSAO
/// </summary>
/// <param name="Weidth"></param>
/// <param name="Height"></param>
/// <param name="PixelFormat"></param>
public void Create(uint Weidth, uint Height, PixelFormat PixelFormat = PixelFormat.PF_R8G8B8)
{
base.Create(Weidth, Height, PixelFormat);
}
#endregion

#region Update
/// <summary>
/// Update SSAO
/// </summary>
public void Update()
{
if (!Enabled)
{
return;
}
ViewPort.MaterialScheme = ("geom");
MaterialManager.Singleton.ActiveScheme = ("geom");

// render using the geom scheme to our viewport
// using the main scene camera
QuadRenderer.Camera.SceneManager._renderScene(QuadRenderer.Camera, ViewPort, false);

base.Update();
}
#endregion

#region Public Member

#endregion
}
}


I also changed some other properties, as in the C++-Code:

myWindow.IsAutoUpdated = false;
myViewport.BackgroundColour = new ColourValue(0, 0, 0, 0);
myViewport.SetClearEveryFrame(false);

myCamera.AspectRatio = (float)(myWindow.Width / (float)myWindow.Height);
myCamera.FOVy = new Degree(60);


And on this way, i created ssao:

QuadRenderer cQR = new QuadRenderer(myITOgre.Camera);

cGeom = new Geom("geom", cQR);
cGeom.Create(myITOgre.RenderWindow.Width, myITOgre.RenderWindow.Height, PixelFormat.PF_FLOAT32_RGBA);

cSSAO = new SSAO("ssao", cQR);
cSSAO.Create(myITOgre.RenderWindow.Width, myITOgre.RenderWindow.Height);

//Debug overlay
ssaoDebugMat = MaterialManager.Singleton.Create("ssao_debug", "Internal");
ssaoDebugMat.CreateTechnique().CreatePass().CreateTextureUnitState().SetTextureName(cSSAO.Texture.Name);

Overlay cOverlay = OverlayManager.Singleton.GetByName("ssao_debug");
cOverlay.GetChild("ssao_debug_panel").MaterialName = ssaoDebugMat.Name;
cOverlay.Show();


Updating everything is done in a Framelistner:

cGeom.Clear();
cGeom.Update();

cSSAO.Clear();
cSSAO.Update();

GameContext.GfxManager.TOgreManager.Singelton.Root.RenderSystem._setViewport(GameContext.GfxManager.TOgreManager.Singelton.Viewport);
GameContext.GfxManager.TOgreManager.Singelton.Root.RenderSystem.ClearFrameBuffer(1 | 2);
GameContext.GfxManager.TOgreManager.Singelton.SceneManager._renderScene(GameContext.GfxManager.TOgreManager.Singelton.Camera, GameContext.GfxManager.TOgreManager.Singelton.Viewport, true);
GameContext.GfxManager.TOgreManager.Singelton.RenderWindow.SwapBuffers(true);


But nothing really changed, no SSAO.
Also the Debug-Overlay is always white, but i don't get any errors.

It would be very nice, if anyone have an idea!

Best regards,
Jo0oker

Jeason

31-05-2011 21:41:48

Hmmm when i tried the last time this SSAO Example in the normal OGRE it doesn't work too