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: 460

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:

(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

Related posts about XNA

Related posts about shaders