Sign in to follow this  
Spa8nky

[C#] Deferred rendering. Post processing quad is not showing anything?

Recommended Posts

Spa8nky    230
Here I have my vertices that cover the screen:
    public class Screen
    {
        // Define Triangles clockwise (TraingleStrip Method) so they face the Camera [TL -> TR -> BL -> BR]
        public static VertexPositionTexture[] Vertices = new VertexPositionTexture[4]
            {
               /*
                *  (-1,1)-----------(1,1)  [x]: -1 -----> 1 
                *      |               |
                *      |               |   [y]:    1
                *      |     (0,0)     |           |
                *      |               |           |
                *      |               |           |
                *  (-1,-1)__________(1,-1)         -1
                */

                // Screen X,Y coordinatates go from (-1,1) [Top Left] to (1,-1) [Bottom Right]
                // .Z coordinate of 0 = Draw on near clipping plane (as close to camera as possible)
                new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0)),                // Top Left
                new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0)),                 // Top Right
                new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)),               // Bottom Left
                new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)),                // Bottom Right
            };
    }

After following some instructions from Catalin Zima's tutorial on how to get directional light with deferred rendering, I have the following method:
            // Set all parameters
            effect_Light_Directional.Parameters["colourMap"].SetValue(RT_Colour.GetTexture());
            effect_Light_Directional.Parameters["normalMap"].SetValue(RT_Normal.GetTexture());
            effect_Light_Directional.Parameters["depthMap"].SetValue(RT_Depth.GetTexture());
            effect_Light_Directional.Parameters["lightDirection"].SetValue(lightDirection);
            effect_Light_Directional.Parameters["colour"].SetValue(colour.ToVector3());
            effect_Light_Directional.Parameters["cameraPosition"].SetValue(camera.Position);
            effect_Light_Directional.Parameters["InvViewProjection"].SetValue(Matrix.Invert(camera.ViewMatrix * camera.ProjectionMatrix));
            effect_Light_Directional.Parameters["halfPixel"].SetValue(pixel_Half);
            
            effect_Light_Directional.Begin();
            effect_Light_Directional.Techniques[0].Passes[0].Begin();

            // Draw a full-screen quad [Post processing effect]       
            graphics_Device.VertexDeclaration = new VertexDeclaration(graphics_Device, VertexPositionTexture.VertexElements);
            graphics_Device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, Screen.Vertices, 0, 2);
            
            effect_Light_Directional.Techniques[0].Passes[0].End();
            effect_Light_Directional.End();

The problem is that nothing is showing up on the screen, it is just black and I am not sure as to why this is happening. The HLSL code for the directional light effect is as follows:
// Texture Maps from render Multiple Render Targets
texture colourMap;			// Diffuse colour (rgb channels) specularIntensity (alpha channel)
texture depthMap;			// Depth
texture normalMap;			// Normals (xyz) specularPower (alpha channel)

//=============================================
//------------- [Texture Samplers] ------------
//=============================================

sampler ColourSampler = sampler_state   
{   
    Texture = <colourMap>;   
       
    MinFilter = Linear;   
    MagFilter = Linear;   
    MipFilter = Linear;   
       
    AddressU = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
    AddressV = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
};

sampler DepthSampler = sampler_state   
{   
    Texture = <depthMap>;   
       
    MinFilter = Point;   
    MagFilter = Point;   
    MipFilter = Point;   
       
    AddressU = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
    AddressV = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
};

sampler NormalSampler = sampler_state   
{   
    Texture = <normalMap>;   
       
    MinFilter = Point;   
    MagFilter = Point;   
    MipFilter = Point;   
       
    AddressU = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
    AddressV = Wrap;   // OR Mirror OR Clamp (Wrap works with Level Editor Grid)
};

//=============================================
//------------------ [Structs] ----------------
//=============================================

struct VertexShaderInput
{
    float3 Position : POSITION0; 
    float2 TexCoord	: TEXCOORD0;   
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord	: TEXCOORD0;   
};

//=============================================
//------------ Technique: Default -------------
//=============================================

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    output.Position = float4(input.Position,1);
    
    // Align texture coordinates    
    //output.TexCoord = input.TexCoord - halfPixel;
	output.TexCoord = input.TexCoord;
	
    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	// Get normal data from the normalMap    
	float4 normalData = tex2D(NormalSampler,input.TexCoord);
	
	// Transform normal back into [-1,1] range    
	float3 normal = 2.0f * normalData.xyz - 1.0f;
	
	// Get specular power, and get it into [0,255] range]    
	float specularPower = normalData.a * 255;
	
	// Get specular intensity from the colorMap    
	float specularIntensity = tex2D(ColourSampler, input.TexCoord).a;
	
	// SPECULAR LIGHTING
	
	// Get depth
	float depthVal = tex2D(DepthSampler,input.TexCoord).r;
	
	// Compute screen-space position
	float4 position;
	
	position.x = input.TexCoord.x * 2.0f - 1.0f;
	position.y = -(input.TexCoord.x * 2.0f - 1.0f);
	position.z = depthVal;
	position.w = 1.0f;
	
	// Transform screen space position to world space
	position = mul(position, InvViewProjection);
	position /= position.w;
	
	// Surface to light vector (opposite direction to light direction)
	float3 lightVector = -normalize(lightDirection);
	
	// Compute diffuse light
	float NdL = max(0,dot(normal,lightVector));
	float3 diffuseLight = NdL * colour.rgb;
	
	// Reflection vector
	float3 reflectionVector = normalize(reflect(lightVector, normal));
	
	// Camera to surface vector    
	float3 directionToCamera = normalize(cameraPosition - position);
	
	// Compute specular light
	float specularLight = specularIntensity * pow( saturate(dot(reflectionVector, directionToCamera)), specularPower);
	
	// Output the two lights
	return float4(diffuseLight.rgb, specularLight);
}

technique Default
{
    pass Pass0
    {		
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}

I can draw my render targets correctly to the screen but I cannot post process them. In other words the following works correctly:
            deferredRendering.SetGBuffer();
            deferredRendering.ClearGBuffer();

            // Draw all objects 
            DrawMyObjects();
                    
            deferredRendering.ResolveGBuffer();
            deferredRendering.DrawGBuffer();
I can also draw a quadrangle that covers the screen using a separate effect file with no problems. However, when I add the following two lines and call the post processing effect, I get nothing:
            GraphicsDevice.Clear(Color.Black);
            deferredRendering.DrawDirectionalLight(new Vector3(1, -1, 0), Color.White);
Does anyone know what might be going wrong here? Thank you.

Share this post


Link to post
Share on other sites
adt7    751
What have you done to try and debug your problem?

First try making the lighting shader output a solid colour (not black, since you're clearing to that already), if that shops up your quad is being drawn correctly. If it doesn't show up try switching the cullmode.

Once you've confirmed that's being drawn correctly, check that your gBuffer is being filled correctly, either by drawing it to screen (if you've following Catalin's tutorial you should have done this already) or saving it to a file.

If your quad is being output correctly and your gBuffer is being filled correctly you should get something that looks like your geometry, only without colours, just lighting.

A few notes about what you have so far:

If you're working in DirectX 9 you need to include the half pixel offset still in your vertex shader.

You don't need to pass your colour texture to the lighting shader, diffuse colour is not involved at this stage.

Your address modes for the normal and deth textures should be set to CLAMP, not WRAP.

Share this post


Link to post
Share on other sites
Resharper    100
Hi! I have the same problem. When i am rendering all textures (GBuffer, color, normal) it draws my geometry. But tutorial says that after applying ClearGBuffer shader Color must have black background, depth - white, normal - gray. But i've got all backgrounds violet and depth blue. What's wrong?

Share this post


Link to post
Share on other sites
Resharper    100
Problem with rendering backgrounds solved. I am using XNA 3.1 and you have to draw this textures using Graphics.SpriteBatch.Begin(SpriteBlendMode.None); instead of Graphics.SpriteBatch.Begin();

Problem with the black screen when rendering lights solved too. Before rendering post process switch off DepthBuffer. As far as i can judge this happens in XNA 3.1:

Graphics.GraphicsDevice.RenderState.DepthBufferEnable = false;


Of course, before rendering scene into GBuffer you have to enable DepthBuffer. Your final code should look something like this:

Graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;
deferredRenderer.Render();
Graphics.GraphicsDevice.RenderState.DepthBufferEnable = false;
GraphicsDevice.Clear(Color.Black);
deferredRendering.DrawDirectionalLight(new Vector3(1, -1, 0), Color.White);



[Edited by - Resharper on November 21, 2009 1:21:43 AM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this