DeferredRenderer.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlimDX;
using SlimDX.Direct3D9;
namespace VoxelSubmarineGameSlimDXTest.DeferredRendering
{
public static class DeferredRenderer
{
private static Sprite sprite;
private static Device device;
private static Texture colorRT;
private static Texture normalRT;
private static Texture depthRT;
private static Texture lightRT;
private static Surface colorRTSurface;
private static Surface normalRTSurface;
private static Surface depthRTSurface;
private static Surface lightRTSurface;
private static Effect clearGBufferEffect;
private static Effect renderGBufferEffect;
private static Effect pointLightEffect;
private static Effect directionalLightEffect;
private static Effect combineFinalEffect;
private static Vector2 halfPixel;
private static Mesh sphereMesh;
///
/// A:0 R:0 G:0 B:0
///
private static Color4 colorTransparent = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
private static Surface backBuffer;
public static void Init(Device argDevice)
{
device = argDevice;
QuadRenderer.Init(device);
int tmpWidth = device.GetBackBuffer(0, 0).Description.Width;
int tmpHeight = device.GetBackBuffer(0, 0).Description.Height;
halfPixel = new Vector2(0.5f / (float)tmpWidth, 0.5f / (float)tmpHeight);
colorRT = new Texture(device, tmpWidth, tmpHeight, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
normalRT = new Texture(device, tmpWidth, tmpHeight, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
depthRT = new Texture(device, tmpWidth, tmpHeight, 1, Usage.RenderTarget, Format.R32F, Pool.Default);
lightRT = new Texture(device, tmpWidth, tmpHeight, 1, Usage.RenderTarget, Format.A8R8G8B8, Pool.Default);
colorRTSurface = colorRT.GetSurfaceLevel(0);
normalRTSurface = normalRT.GetSurfaceLevel(0);
depthRTSurface = depthRT.GetSurfaceLevel(0);
lightRTSurface = lightRT.GetSurfaceLevel(0);
clearGBufferEffect = Effect.FromFile(device, GameResources.ClearGBufferShaderPath, ShaderFlags.None);
renderGBufferEffect = Effect.FromFile(device, GameResources.RenderGBufferShaderPath, ShaderFlags.None);
pointLightEffect = Effect.FromFile(device, GameResources.PointLightShaderPath, ShaderFlags.None);
directionalLightEffect = Effect.FromFile(device, GameResources.DirectionalLightShaderPath, ShaderFlags.None);
combineFinalEffect = Effect.FromFile(device, GameResources.CombineFinalShaderPath, ShaderFlags.None);
sphereMesh = Mesh.CreateSphere(device, 1.0f, 8, 8);
sprite = new Sprite(device);
}
public static void CleanUp()
{
clearGBufferEffect.Dispose();
renderGBufferEffect.Dispose();
pointLightEffect.Dispose();
directionalLightEffect.Dispose();
combineFinalEffect.Dispose();
colorRTSurface.Dispose();
normalRTSurface.Dispose();
depthRTSurface.Dispose();
lightRTSurface.Dispose();
colorRT.Dispose();
normalRT.Dispose();
depthRT.Dispose();
lightRT.Dispose();
sphereMesh.Dispose();
}
private static void ClearGBuffer()
{
clearGBufferEffect.Begin();
clearGBufferEffect.BeginPass(0);
QuadRenderer.Render(new Vector2(-1.0f, -1.0f), new Vector2(1.0f, 1.0f));
clearGBufferEffect.EndPass();
clearGBufferEffect.End();
}
private static void RenderGBuffer()
{
int tmpTextureTileSizeReal = 16;
int tmpTextureTilesX = World.World.Tileset.GetLevelDescription(0).Width / tmpTextureTileSizeReal;
int tmpTextureTilesY = World.World.Tileset.GetLevelDescription(0).Height / tmpTextureTileSizeReal;
float tmpTextureTileSize = (float)tmpTextureTileSizeReal / (float)World.World.Tileset.GetLevelDescription(0).Width;
renderGBufferEffect.SetValue("World", Matrix.Identity);
renderGBufferEffect.SetValue("View", World.World.GameCamera.View);
renderGBufferEffect.SetValue("Projection", World.World.GameCamera.Projection);
renderGBufferEffect.SetTexture("Texture", World.World.Tileset);
renderGBufferEffect.SetValue("cameraPosition", World.World.GameCamera.Position);
renderGBufferEffect.SetValue("halfPixel", halfPixel);
renderGBufferEffect.SetValue("textureTilesX", tmpTextureTilesX);
renderGBufferEffect.SetValue("textureTilesY", tmpTextureTilesY);
renderGBufferEffect.SetValue("textureTileSize", tmpTextureTileSize);
renderGBufferEffect.Begin();
renderGBufferEffect.BeginPass(0);
//Draw the whole scene here
World.World.GameMap.RenderChunks();
renderGBufferEffect.EndPass();
renderGBufferEffect.End();
}
private static void DrawDirectionalLight(Vector3 argLightDirection, Color3 argColor)
{
directionalLightEffect.SetTexture("colorMap", colorRT);
directionalLightEffect.SetTexture("normalMap", normalRT);
directionalLightEffect.SetTexture("depthMap", depthRT);
directionalLightEffect.SetValue("lightDirection", argLightDirection);
directionalLightEffect.SetValue("Color", argColor);
directionalLightEffect.SetValue("cameraPosition", World.World.GameCamera.Position);
directionalLightEffect.SetValue("InvertViewProjection",
Matrix.Invert(World.World.GameCamera.View * World.World.GameCamera.Projection));
directionalLightEffect.SetValue("halfPixel", halfPixel);
directionalLightEffect.Begin();
directionalLightEffect.BeginPass(0);
QuadRenderer.Render(new Vector2(-1.0f, -1.0f), new Vector2(1.0f, 1.0f));
directionalLightEffect.EndPass();
directionalLightEffect.End();
}
/*private static void RenderPointLight(Vector3 argPosition)
{
sphereMesh.DrawSubset(0);
}*/
private static void RenderLights()
{
DrawDirectionalLight(new Vector3(0.5f, -0.5f, 0.5f), new Color3(1.0f, 0.5f, 0.0f));
//DrawDirectionalLight(new Vector3(0.5f, 0.5f, -0.5f), new Color3(0.0f, 0.0f, 0.5f));
//DrawDirectionalLight(new Vector3(-0.5f, -0.5f, -0.5f), new Color3(0.0f, 1.0f, 0.0f));
}
private static void CombineFinal()
{
combineFinalEffect.SetTexture("colorMap", colorRT);
combineFinalEffect.SetTexture("lightMap", lightRT);
combineFinalEffect.SetTexture("depthMap", depthRT);
combineFinalEffect.SetValue("halfPixel", halfPixel);
combineFinalEffect.SetValue("cameraPosition", World.World.GameCamera.Position);
combineFinalEffect.SetValue("InvertViewProjection", Matrix.Invert(World.World.GameCamera.View
* World.World.GameCamera.Projection));
combineFinalEffect.Begin();
combineFinalEffect.BeginPass(0);
QuadRenderer.Render(new Vector2(-1.0f, -1.0f), new Vector2(1.0f, 1.0f));
combineFinalEffect.EndPass();
combineFinalEffect.End();
}
public static void RenderFrame()
{
backBuffer = device.GetRenderTarget(0);
device.SetRenderTarget(0, colorRTSurface);
device.SetRenderTarget(1, normalRTSurface);
device.SetRenderTarget(2, depthRTSurface);
device.Clear(ClearFlags.All, colorTransparent, 1.0f, 0);
// Clear the GBuffer here
ClearGBuffer();
// Render the GBuffer here
RenderGBuffer();
device.SetRenderTarget(0, lightRTSurface);
device.SetRenderTarget(1, null);
device.SetRenderTarget(2, null);
device.Clear(ClearFlags.All, colorTransparent, 1.0f, 0);
device.SetRenderState(RenderState.AlphaBlendEnable, true);
device.SetRenderState(RenderState.SourceBlend, Blend.One);
device.SetRenderState(RenderState.SourceBlendAlpha, Blend.One);
device.SetRenderState(RenderState.DestinationBlend, Blend.One);
device.SetRenderState(RenderState.DestinationBlendAlpha, Blend.One);
// Render the lights
RenderLights();
device.SetRenderTarget(0, backBuffer);
device.SetRenderState(RenderState.AlphaBlendEnable, false);
// Combine the render target data into the final image
CombineFinal();
/*sprite.Begin(SpriteFlags.None);
sprite.Draw(lightRT, new Color4(1.0f, 1.0f, 1.0f, 1.0f));
sprite.End();*/
}
}
}
I can post the shader files here too, but there's about 4 of them, so that's only if somebody wants me to, so as not to clutter the place.I basically copied them from the XNA example, and it being HLSL I didn't have to change it at all, since it's exactly the same both in XNA and SlimDX. It worked in XNA, so it should work here.
I'm getting this with the code above:

So the question is: what am I doing wrong and how do I fix it?
I'm using the Express edition of VS, so debugging this is quite difficult. I tried using PIX, but I'm not very experienced with it (or D3D) and it didn't really return anything too useful.




















