Alright, so...
This is how I draw my opaque content:
//If there's opaque geometry
if (this.renderQueue.Count > 0)
{
// Set States
this.device.BlendState = BlendState.Opaque;
this.device.DepthStencilState = DepthStencilState.Default;
this.device.RasterizerState = RasterizerState.CullCounterClockwise;
// Clear GBuffer
ClearGBuffer();
foreach (Mesh mesh in this.renderQueue)
{
// Make our GBuffer
MakeGBuffer(mesh);
}
if (this.useLighting)
{
// Make LightMap
MakeLightMap();
}
// Compose our final image
ComposeFinalImage(null);
}
ClearGBuffer:
private void ClearGBuffer()
{
// Set to ReadOnly depth for now
this.device.DepthStencilState = DepthStencilState.DepthRead;
// Set GBuffer Render Targets
this.device.SetRenderTargets(GBufferTargets);
// Set Clear Effect
this.Clear.CurrentTechnique.Passes[0].Apply();
// Draw
this.fsq.Draw(device);
}
MakeLightMap:
/// <summary>
/// Creates our LightMap
/// </summary>
private void MakeLightMap()
{
// Set LightMap RenderTarget
this.device.SetRenderTarget(LightMap);
// Clear to transparent black
this.device.Clear(ClearOptions.Target, Color.Transparent, 1.0f, 0);
// Set States
this.device.BlendState = LightMapBS;
this.device.DepthStencilState = DepthStencilState.DepthRead;
// GBuffer Sampler 1 (Depth)
this.device.Textures[0] = this.GBufferTargets[0].RenderTarget;
this.device.SamplerStates[0] = SamplerState.PointClamp;
// GBuffer Sampler 2 (Albedo)
this.device.Textures[1] = this.GBufferTargets[1].RenderTarget;
this.device.SamplerStates[1] = SamplerState.PointClamp;
// GBuffer Sampler 3 (Normal)
this.device.Textures[2] = this.GBufferTargets[2].RenderTarget;
this.device.SamplerStates[2] = SamplerState.PointClamp;
// Calculate inverseView
Matrix inverseView = Matrix.Invert(this.engine.GetCamera.View);
// Calculate inverseViewProjection
Matrix inverseViewProjection = Matrix.Invert(this.engine.GetCamera.View * this.engine.GetCamera.Projection);
// Set the Directional Lights geometry buffers
fsq.ReadyBuffers(device);
foreach (DirectionalLightSource light in this.lightManager.GetDirectionalLights)
{
// Set Directional Light parameters
this.DeferredLighting.CurrentTechnique = this.DeferredLighting.Techniques["Directional"];
this.DeferredLighting.Parameters["inverseViewProjection"].SetValue(inverseViewProjection);
this.DeferredLighting.Parameters["inverseView"].SetValue(inverseView);
this.DeferredLighting.Parameters["CameraPosition"].SetValue(this.engine.GetCamera.Position);
this.DeferredLighting.Parameters["GBufferTextureSize"].SetValue(this.GBufferTextureSize);
this.DeferredLighting.Parameters["LightDirection"].SetValue(light.Direction);
this.DeferredLighting.Parameters["LightColor"].SetValue(light.Color);
this.DeferredLighting.Parameters["AmbientColor"].SetValue(this.lightManager.GetAmbientColor());
this.DeferredLighting.Parameters["LightIntensity"].SetValue(light.Intensity);
// Apply
this.DeferredLighting.CurrentTechnique.Passes[0].Apply();
// Draw FullscreenQuad
this.fsq.JustDraw(device);
}
// Set states off
this.device.BlendState = BlendState.Opaque;
this.device.RasterizerState = RasterizerState.CullCounterClockwise;
this.device.DepthStencilState = DepthStencilState.DepthRead;
this.device.SetRenderTarget(null);
}
MakeGBuffer:
GBuffer.Parameters["View"].SetValue(camera.View);
GBuffer.Parameters["Projection"].SetValue(camera.Projection);
GBuffer.Parameters["farClip"].SetValue(camera.FarClip);
GBuffer.Parameters["materialID"].SetValue((int)material.GetMaterialID);
//Get Transforms
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
//Draw Each ModelMesh
foreach (ModelMesh modelmesh in model.Meshes)
{
//Draw Each ModelMeshPart
foreach (ModelMeshPart part in modelmesh.MeshParts)
{
//Set Vertex Buffer
device.SetVertexBuffer(part.VertexBuffer, part.VertexOffset);
//Set Index Buffer
device.Indices = part.IndexBuffer;
WorldMatrix = transforms[modelmesh.ParentBone.Index] * transform;
//Set World
GBuffer.Parameters["World"].SetValue(WorldMatrix);
SetShaderVariables(part, GBuffer, true);
//Set WorldIT
GBuffer.Parameters["WorldViewIT"].SetValue(Matrix.Transpose(Matrix.Invert((transforms[modelmesh.ParentBone.Index] * transform) * camera.View)));
// Apply pass
GBuffer.CurrentTechnique.Passes[0].Apply();
//Draw
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount);
}
}
}
Compose:
/// <summary>
/// Composes the picture
/// </summary>
private void ComposeFinalImage(RenderTarget2D output)
{
// Set Composition Target
this.device.SetRenderTargets(depthTarget, compositionTarget);
// Clear
//this.device.Clear(ClearOptions.Target, Color.Transparent, 1.0f, 0);
// Set Albedo Buffer
this.device.Textures[0] = this.GBufferTargets[1].RenderTarget;
this.device.SamplerStates[0] = SamplerState.AnisotropicClamp;
// Set LightMap
this.device.Textures[1] = LightMap;
this.device.SamplerStates[1] = SamplerState.PointClamp;
// Set Effect parameters
this.Compose.Parameters["GBufferTextureSize"].SetValue(this.GBufferTextureSize);
// Apply
this.Compose.CurrentTechnique.Passes[0].Apply();
// Draw FullscreenQuad
this.fsq.Draw(device);
}
And here's how I draw transparent geometry
/// <summary>
/// Renders transparent geometry sorted back-to-front
/// </summary>
private void DrawTransparentGeometry()
{
// Clear DepthStencil Buffer with TransparentBlack
//this.device.Clear(ClearOptions.Stencil, Color.Black, 1.0f, 0);
if (this.transparentMeshRenderQueue.Count > 0)
{
// Set States
//this.device.BlendState = BlendState.AlphaBlend;
this.device.DepthStencilState = DepthStencilState.Default;
this.device.RasterizerState = RasterizerState.CullCounterClockwise;
// Go through each mesh in transparent mesh render queue
for (int i = 0; i < this.transparentMeshRenderQueue.Count; i++)
{
// If there's more than one mesh inside the queue
if (this.transparentMeshRenderQueue.Count > (i + 1))
{
// If an object's depth is in front of the other one's, swap their places
if (this.transparentMeshRenderQueue[i].GetPosition.Z < this.transparentMeshRenderQueue[i + 1].GetPosition.Z)
{
TransparentMesh mesh = this.transparentMeshRenderQueue[i + 1];
this.transparentMeshRenderQueue[i + 1] = this.transparentMeshRenderQueue[i];
this.transparentMeshRenderQueue[i] = mesh;
}
}
}
// Draw Mesh
for (int i = 0; i < this.transparentMeshRenderQueue.Count; i++)
{
if (this.transparentMeshRenderQueue[i].mesh.GetMaterial.useLighting)
{
foreach (DirectionalLightSource light in this.lightManager.GetDirectionalLights)
{
this.transparentMeshRenderQueue[i].mesh.GetMaterial.GetEffect.Parameters["CameraPosition"].SetValue(this.engine.GetCamera.Position);
this.transparentMeshRenderQueue[i].mesh.GetMaterial.GetEffect.Parameters["LightDirection"].SetValue(light.Direction);
this.transparentMeshRenderQueue[i].mesh.GetMaterial.GetEffect.Parameters["LightColor"].SetValue(light.Color);
this.transparentMeshRenderQueue[i].mesh.GetMaterial.GetEffect.Parameters["AmbientColor"].SetValue(this.lightManager.GetAmbientColor());
this.transparentMeshRenderQueue[i].mesh.GetMaterial.GetEffect.Parameters["LightIntensity"].SetValue(light.Intensity);
this.transparentMeshRenderQueue[i].mesh.DrawForward(device, this.engine.GetCamera);
}
}
else
{
this.transparentMeshRenderQueue[i].mesh.DrawForward(device, this.engine.GetCamera);
}
}
}
this.device.SetRenderTarget(null);
}
Edited by lipsryme, 09 July 2012 - 11:18 AM.