XNA 4 Deferred Rendering deforms the model
        Posted  
        
            by 
                Tomáš Bezouška
            
        on Game Development
        
        See other posts from Game Development
        
            or by Tomáš Bezouška
        
        
        
        Published on 2011-11-21T17:46:59Z
        Indexed on 
            2011/11/21
            18:11 UTC
        
        
        Read the original article
        Hit count: 588
        
I have a problem when rendering a model of my World - when rendered using BasicEffect, it looks just peachy. Problem is when I render it using deferred rendering. See for yourselves:
- what it looks like: http://imageshack.us/photo/my-images/690/survival.png/
 - what it should look like: http://imageshack.us/photo/my-images/521/survival2.png/
 
(Please ignora the cars, they shouldn't be there. Nothing changes when they are removed)
Im using Deferred renderer from
- www.catalinzima.com/tutorials/deferred-rendering-in-xna/introduction-2/
 
except very simplified, without the custom content processor. Here's the code for the GBuffer shader:
float4x4 World;
float4x4 View;
float4x4 Projection;
float specularIntensity = 0.001f;
float specularPower = 3; 
texture Texture;
sampler diffuseSampler = sampler_state
{
    Texture = (Texture);
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
    MIPFILTER = LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float2 TexCoord : TEXCOORD0;
};
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float3 Normal : TEXCOORD1;
    float2 Depth : TEXCOORD2;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
    output.TexCoord = input.TexCoord;                            //pass the texture coordinates further
    output.Normal = mul(input.Normal,World);                   //get normal into world space
    output.Depth.x = output.Position.z;
    output.Depth.y = output.Position.w;
    return output;
}
struct PixelShaderOutput
{
    half4 Color : COLOR0;
    half4 Normal : COLOR1;
    half4 Depth : COLOR2;
};
PixelShaderOutput PixelShaderFunction(VertexShaderOutput input)
{
    PixelShaderOutput output;
    output.Color = tex2D(diffuseSampler, input.TexCoord);            //output Color
    output.Color.a = specularIntensity;                                              //output SpecularIntensity
    output.Normal.rgb = 0.5f * (normalize(input.Normal) + 1.0f);    //transform normal domain
    output.Normal.a = specularPower;                                            //output SpecularPower
    output.Depth = input.Depth.x / input.Depth.y;                           //output Depth
    return output;
}
technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
And here are the rendering parts in XNA:
public void RednerModel(Model model, Matrix world)
        {
            Matrix[] boneTransforms = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(boneTransforms);            
            Game.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            Game.GraphicsDevice.BlendState = BlendState.Opaque;
            Game.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            foreach (ModelMesh mesh in model.Meshes)
            {
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
                    GBufferEffect.Parameters["View"].SetValue(Camera.Instance.ViewMatrix);
                    GBufferEffect.Parameters["Projection"].SetValue(Camera.Instance.ProjectionMatrix);
                    GBufferEffect.Parameters["World"].SetValue(boneTransforms[mesh.ParentBone.Index] * world);
                    GBufferEffect.Parameters["Texture"].SetValue(meshPart.Effect.Parameters["Texture"].GetValueTexture2D());
                    GBufferEffect.Techniques[0].Passes[0].Apply();
                    RenderMeshpart(mesh, meshPart);
                }
            }    
        }
        private void RenderMeshpart(ModelMesh mesh, ModelMeshPart part)
        {
            Game.GraphicsDevice.SetVertexBuffer(part.VertexBuffer);
            Game.GraphicsDevice.Indices = part.IndexBuffer;
            Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,
                                                          0, 0, part.NumVertices,
                                                          part.StartIndex, part.PrimitiveCount);
        }
I import the model using the built in content processor for FBX. The FBX is created in 3DS Max. I don't know the exact details of that export, but if you think it might be relevant, I will get them from my collegue who does them.
What confuses me though is why the BasicEffect approach works... seems the FBX shouldnt be a problem.
Any thoughts? They will be greatly appreciated :)
© Game Development or respective owner