What’s next inline?

Well, after resolving the issue of the PointLight, it highlighted the fact that there is no real way of adding a new PointLight.  So, I’m going to start work on a LightManager class that will make this a lot easier.  As soon as I’ve done this, I’ll create a post explaining what has been implemented with a step-by-step guide so you can implement it yourselves.

Adding new hemispheric light

It’s been a short while since I’ve posted, so I thought I’d let you know what I’ve been working on. Whilst I’ve managed to finish of the SSAO implementation, I have been trying to implement a new light. So far, it’s going well, but I have a problem with the models appearing transparent.

So, I’m looking into this at that moment and will post news as it happens.

Adding a basic Light Manager – Part 1

In the last post we implemented Point lights, but it was hard coded into the “DeferredRenderer” class. In this post, we’ll implement a very basic Light Manager that will store the lights and render them. This is a very simple implementation. I’d really like you, the community, to help implement a decent Light Manager, but for the time being we’ll use this.

In the “ProjectVanquish” project, add a new Class under the “Core” folder called “LightManager”. Add the following namespaces:

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using ProjectVanquish.Cameras;
using ProjectVanquish.Renderers;

Add the following variables:

ContentManager content;
GraphicsDevice device;
Effect directionalLightEffect, pointLightEffect;
QuadRenderer fullscreenQuad;
Vector2 halfPixel;
Model sphere;

Now we can create our constructor:

public LightManager(GraphicsDevice device, ContentManager content)
    this.content = content;
    this.device = device;
    directionalLightEffect = content.Load<Effect>("Shaders/Lights/DirectionalLight");
    pointLightEffect = content.Load<Effect>("Shaders/Lights/PointLight");
    fullscreenQuad = new QuadRenderer(device);
    halfPixel = new Vector2()
        X = 0.5f / (float)device.PresentationParameters.BackBufferWidth,
        Y = 0.5f / (float)device.PresentationParameters.BackBufferHeight
    sphere = content.Load<Model>("Models/sphere");

As you can see, we are now loading the “Sphere” Model in our “LightManager” constructor, so we should remove this from the “DeferredRenderer” class as well.

We now have duplicated code as we are loading the light Effects in the “DeferredRenderer” class and the new “LightManager” class. Remove the instantiation code from the “DeferredRenderer” class, but not the rendering methods yet. We need to move these methods into the “LightManager” class, so we’ll start with the “DrawLights” method. Cut the method and paste it into the “LightManager” class. We’ll get some errors now, because the RenderTargets don’t exist in this class. Alter the “DrawLights” method declaration to the following:

public void DrawLights(RenderTarget2D colorRT, RenderTarget2D normalRT, RenderTarget2D depthRT, RenderTarget2D lightRT, FreeCamera camera)

Find the “DrawDirectionalLight” and “DrawPointLight” methods in the “DeferredRenderer” class and cut and paste into the “LightManager” class. Both method declarations will now need to change in order to work. We’ll start with the new declaration of the “DrawDirectionalLight” method:

void DrawDirectionalLight(RenderTarget2D colorRT, RenderTarget2D normalRT, RenderTarget2D depthRT, FreeCamera camera, Vector3 lightDirection, Color color)

And the new “DrawPointLight” method:

void DrawPointLight(RenderTarget2D colorRT, RenderTarget2D normalRT, RenderTarget2D depthRT, FreeCamera camera, Vector3 lightPosition, Color color, float lightRadius, float lightIntensity)

The last thing left to do is to find sceneManager.Camera instances and change them to camera.

Back in our “DeferredRenderer” class, let’s instantiate this new “LightManager” class. Add a variable:

private LightManager lightManager;

In the constructor, instantiate it:

lightManager = new LightManager(device, content);

The last thing left to do is to alter the “DrawLights” method in the “Draw” method. This now becomes:

lightManager.DrawLights(colorRT, normalRT, depthRT, lightRT, sceneManager.Camera);

Build the solution and you should get no errors. If you run the code you should still see our scene from the last post. In the next part, we’ll extend this “LightManager” class by creating a “PointLight” class which we can instantiate and control it’s position, direction etc. from the “DeferredRenderer” class.