An SSAO fix

I’m not sure if I was the only one having an issue with the SSAO, but I’ve found a fix. The values in the Shader, particularly the samples in the PixelShaderFunction, were wrong. Here is the correct settings:

//Sample Vectors
float4 samples[8] =
{
	float4(0.355512, 	-0.709318, 	-0.102371,	0.0 ),
	float4(0.534186, 	0.71511, 	-0.115167,	0.0 ),
	float4(-0.87866, 	0.157139, 	-0.115167,	0.0 ),
	float4(0.140679, 	-0.475516, 	-0.0639818,	0.0 ),
	float4(-0.0796121, 	0.158842, 	-0.677075,	0.0 ),
	float4(-0.0759516, 	-0.101676, 	-0.483625,	0.0 ),
	float4(0.12493, 	-0.0223423,	-0.483625,	0.0 ),
	float4(-0.0720074, 	0.243395, 	-0.967251,	0.0 )
};

A Shadow Update

It has been a while since I’ve posted the latest progress with the Shadow Mapping. I’ve been looking at it today and made some progress. It is still not fixed, but the screenshot below shows signs of hope.

To view or not to view…

In this post we’ll be introducing Frustum culling. We’ll be adding to the Actor class so we can determine which models are currently in the view frustum and only render those. To do this, we’ll add a BoundingSphere property to the Actor class:

public BoundingSphere BoundingSphere
{
    get { return new BoundingSphere(Position, model.Meshes[0].BoundingSphere.Radius); }
}

With this in place, all we need to do is make a slight amendment to the SceneManager class. In the Draw method, alter the foreach statement to the following:

foreach (Actor actor in models.Where(a => a.BoundingSphere.Intersects(
                                          CameraManager.GetActiveCamera().BoundingFrustum)))
    actor.Draw();

If you don’t get a Where method in the Intellisense, add the following namespace:

using System.Linq;

The new foreach statement will check all models to see if they intersect with the current view frustum and only return those models that are in view.

An appeal…

Don’t worry, I’m not asking for money. I just need someone to help out with the shadows. The code is available at the Codeplex page. I have been tearing hair out for the last couple of days and I could really do with someone else taking a look at what I have done wrong. Anyone fancy taking a look? For those who are on gamedev.stackexchange.com, I’ve posted a question here and I’ll be posting a reward of 200 points as soon as I can.

Also, if you’d like to be a member of the development team, drop me a comment.

Slight shuffle of code

In the latest changeset, I’ve moved the rendering from the “SceneManager” class into the “Actor” class using a new interface, “IRenderable”. I’m looking at creating an “ICullable” as well in order to only render those models that will appear in the view frustum.

Another change I made was for the “PhysicsManager”. If you have a quad core processor, this will now add 3 threads to the “PhysicsManager”. Vigrid pointed out that he had been burnt in the past by allocating a thread for all processors, so rather than learn the hard-way, it’s been to re-allocated 🙂

Extending the SceneManager and introducing….

Yes, I’ve finally managed got around to implementing BEPU Physics. This has meant introducing a new “PhysicsManager” class and extending the “SceneManager” class, but it’s worth it. If you haven’t already, download the latest code from the link above (I’m using 1.1.0). In the “ProjectVanquish” project, add a reference to the BEPU DLL.

We’ll start with the new “PhysicsManager” class. In the “Core” folder, add a new class called “PhysicsManager” and include the following namespaces:

using BEPUphysics;
using BEPUphysics.Constraints;
using BEPUphysics.Settings;
using Microsoft.Xna.Framework;
using ProjectVanquish.Models;

Add the following variables:

private Space space;
private IList<PhysicsObject> physicsObjects; 

PhysicsObject doesn’t exist yet, so you’ll have to fight with Visual Studio for the time being with regards the Intellisense. Let’s create the constructor:

public PhysicsManager(Vector3 gravity)
{
    space = new Space();
    space.ForceUpdater.Gravity = gravity;
    SolverSettings.DefaultMinimumIterations = 2;
    MotionSettings.DefaultPositionUpdateMode = BEPUphysics.PositionUpdating.PositionUpdateMode.Continuous;
    MotionSettings.UseExtraExpansionForContinuousBoundingBoxes = true;
    MotionSettings.CoreShapeScaling = 0.99f;
    space.Solver.IterationLimit = 20;

    // Check if we can use mutli-threading
    if (Environment.ProcessorCount > 1)
    {
        for (int i = 0; i < Environment.ProcessorCount; i++)
            space.ThreadManager.AddThread();

        space.BroadPhase.AllowMultithreading = true;
    }

    physicsObjects = new List<PhysicsObject>();
} 

In the constructor we are instantiating a new BEPU physics object and setting some default values. We also check to see if we can use multi-threading that the BEPU engine now supports. Straight forward enough. We’ll add some properties:

public IList<PhysicsObject> PhysicsObjects 
{ 
    get { return physicsObjects; } 
}

public Space Space 
{ 
    get { return space; } 
} 

This will be used in the “SceneManager” class. Lastly, we just need an “Update” method:

public void Update(GameTime gameTime)
{
    space.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
} 

Excellent. That is our “PhysicsManager” class complete. Let’s extend our “SceneManager” class to use this new class. Open the “SceneManager” class and declare a new variable:

static PhysicsManager physicsManager;

In the constructor, we’ll instantiate it:

physicsManager = new PhysicsManager(new Vector3(0, -9.81f, 0));

This will create an earth-like gravity. We’ll create a static property so we can access this from the “PhysicsManager” class:

public static PhysicsManager PhysicsManager 
{ 
    get { return physicsManager; } 
}

The last part of the “SceneManager” class is to update the “PhysicsManager” in the “Update” method:

physicsManager.Update(gameTime);

That’s all we need to do with the “SceneManager”. The last thing on the check-list is the new “PhysicsObject” class. Add a new class in the “Models” folder called “PhysicsObject” and add in the following namespaces:

using BEPUphysics.Entities;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.MathExtensions;
using Microsoft.Xna.Framework;
using ProjectVanquish.Core;

Make the class public abstract:

public abstract class PhysicsObject

Declare the following variables:

bool movable = false;
Entity entity;
float mass = 1f;

Add a constructor:

public PhysicsObject(bool isMovable)
{
    movable = isMovable;
    InitializeEntity();
} 

In the constructor, we are declaring if the object is movable or static. We are also calling the “InitializeEntity” method. We have 2 methods to add:

protected void InitializeEntity()
{
    entity = new Box(Vector3.Zero, 0f, 0f, 0f, mass);
    SceneManager.PhysicsManager.PhysicsObjects.Add(this);
}

public void Remove()
{
    entity.Space.Remove(entity);
    SceneManager.PhysicsManager.PhysicsObjects.Remove(this);
}

The first initializes a new “Box” object entity and adds it to the “PhysicsManager” list, whilst the second removes the object. That’s all for now with this class. We will be returning to it to add properties later on, but for now, you have successfully integrated BEPU Physics into the engine.

Extending the Actor class

In this post we’ll extend the “Actor” class to include a few more useful properties. We’ll start of by creating a new folder under the “Models” folder called “Interfaces”. In this new folder, create an interface called “IEntity”. Add the following namespaces:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

The interface will look like below:

interface IEntity
{
    BoundingBox BoundingBox { get; }

    Model Model { get; set; }

    Vector3 Position { get; set; }

    Vector3 Rotation { get; set; }

    Vector3 Scale { get; set; }
}

That’s all we need for the interface. Now we just need to hook that up with the “Actor” class. Open the “Actor” class and change the class declaration to:

public class Actor : IEntity

We need to add in the new properties from the interface into our “Actor” class:

public BoundingBox BoundingBox 
{ 
    get { return new BoundingBox(Position - Scale / 2f, Position + Scale / 2f); }
}

public Vector3 Position 
{ 
    get { return position; } 
    set { position = value; } 
}

public Vector3 Rotation 
{ 
    get { return rotation; } 
    set { rotation = value; } 
}

public Vector3 Scale 
{ 
    get { return scale; } 
    set { scale = value; } 
}

That’s it. We now have a calculated BoundingBox for our model which will come in handy when we introduce the Physics part of the engine.

SSAO Fix

I was running through some code and stumbled across a problem with the Screen Space Ambient Occlusion. When I started to debug this, I noticed that the output of the RenderTarget was a solid grey window. After looking into it in more detail, I released that I wasn’t setting the correct RenderTarget in the Draw code. I’ve now corrected this, but I think it could still do with some work as it looks as if something is slightly wrong with it. However, whilst I had my debugging hat on, I got stuck into the Shadow Mapping. I have managed to fix the Depth RenderTarget, but the Shadow Occlusion is still causing a slight issue. I’m slowly but surely getting there.

SSAO Off:

SSAO On:

By Neil_Knight Posted in XNA Tagged ,

New CameraManager class

More improvements have been added with the introduction of a new “CameraManager” class. Overall, the changes were quite large, so I’ll sum up the amends here but the full version can be found here.

The idea behind the “CameraManager” class was to allow multiple cameras to be instantiated and used. Before, everything was hard-coded to a “FirstPersonCamera” and now the camera classes inherit from a new “ICamera” interface. This allows for a camera class to be passed through the engine without actually knowing what type of camera it is. The new “CameraManager” class sits inside of the “Core” folder. It has 4 simple methods which allow you to add, remove, set and get a camera. The “SceneManager” class has been altered to automatically create a “FirstPersonCamera” and assigns a name of “Default”. I’ll quickly run through the new methods:

public static void AddCamera(string name, ICamera camera);

“AddCamera” allows you to add a new camera. As it’s a static method (and so are the other methods), you use it like:

CameraManager.AddCamera("Camera1", new PerspectiveCamera(MathHelper.PiOver2, 
                                                         GraphicsDevice.Viewport.AspectRatio, 
                                                         1.0f, 100.0f)); 
public static ICamera GetActiveCamera();

“GetActiveCamera” does exactly what it says, it will return the camera that is currently set as active. If no camera is found, then it will throw an exception.

public static void RemoveCamera(string name);

“RemoveCamera” will remove the camera with the specified name.

public static void SetActiveCamera(string name);

“SetActiveCamera” will assign the active camera to the specified name. If the specified camera name does not exist in the camera collection, it will throw an exception.

That is pretty much it. Just a quick summary post of the new class. I would download the latest changeset to see the implications that the new class has had on the structure of the engine. Thanks to the new interface “ICamera”, passing cameras between renderers is now a lot easier.