XNA Creators Club Online
Page 1 of 1 (11 items)
Sort Posts: Previous Next

Gears of War in XNA

Last post 3/10/2008 2:29 PM by khronos. 10 replies.
  • 3/9/2008 6:29 PM

    Gears of War in XNA

    Hi,
    I'm working on a shader for rendering Gears of War's main character, but I have a problem.
    A vertical cut appears at the middle of the model.
    I know that the problem has to do with the shader and not with the model, but I don't know what I'm doing wrong.
    Here's the source code in case anyone can help. Thanks.

    http://www.codeplex.com/XNACommunity/Wiki/View.aspx?title=GearsOfWar





  • 3/10/2008 7:08 AM In reply to

    Re: Gears of War in XNA

    I hate to see  a post go unattended, so here is my best guess.

    In your vertex shader you get the directionToLight which you pass to your pixel shader where you use to get some dot products for lighting. 

    It may be that using the vertex to get the light direction to use on a per pixel basis might not be a fine enough angle resolution. 

    Since lightposition is a global, you might try moving the calculation of the light direction to the pixel shader rather than the vertex shader

    try putting

    lightdirection = normalize(lightposition - input.worldposition)

    in the pixel shader whenever you want light direction.

    EDIT: I loaded it up and tried my suggestion, and it made no real difference in appearance.  I went through killing off each lighting variable one by one to see which one may be the main contributor, and that didn't tell me anything.  If you just take your normals from the map and rotate them based on the world matrix, the effect goes away,( along with some others. ) It just looks like the normals are off a bit and react too dramatically to being a little bit in out of line with the light. Mabe that is a consequence of the map, or your tangent manipulations.  I dunno.. it was beyond my knowledge scope to begin with

     

    Good luck

    Byron

    ..shaders make you feel... powerful, or very very stupid.
    http://drjbn.spaces.live.com/
  • 3/10/2008 10:43 AM In reply to

    Re: Gears of War in XNA

    It looks to me like the FBX exporter used was not using shared vertices for normal generation. Thus, you end up with something like this:

    |_|_|_/

    instead of

    |_|_|_|

    (Excuse the bad line art, I dont have photoshop on the machine I'm currently on.)

    Check your FBX exporter for a 'Share vertices' option, and try that.

  • 3/10/2008 1:32 PM In reply to

    Re: Gears of War in XNA

    Could you mark the areas you think are wrong in those screen shots?

    If there is a line along which lighting changes drastically, that's often because of a change in handedness of the tangent basis. You have to detect such a change, and adjust in your tangent space normal mapping code, if that's the case.
    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
  • 3/10/2008 2:29 PM In reply to

    Re: Gears of War in XNA

    Hi,
    Thanks for all the posts, but I still haven't figured out where the problem is. I think that it has to do with the tangent space. Here are two screenshots where you can see the problem and the source code. I will continue searching for a solution, and if I can manage to find one I will post it.

    Up to now I know that:
    1. It is not related to calculating the lightDirection in the vertex shader.
    2. It's not a problem with the model, because I have tried it with other models and the same thing happens.

    float4x4 World;
    float4x4 View;
    float4x4 Projection;

    float3 cameraPosition;

    //light properties
    float3 lightPosition;
    float4 ambientLightColor;
    float4 diffuseLightColor;
    float4 specularLightColor;

    //material properties
    float specularPower = 16;
    float specularIntensity = 1;


    texture2D Texture;
    texture2D NormalMap;
    texture2D EmissiveMap;
    texture2D SpecularMap;

    sampler2D DiffuseTextureSampler = sampler_state
    {
        Texture = <Texture>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D NormalTextureSampler = sampler_state
    {
        Texture = <NormalMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D EmissiveTextureSampler = sampler_state
    {
        Texture = <EmissiveMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D SpecularTextureSampler = sampler_state
    {
        Texture = <SpecularMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };


    struct VertexShaderInput
    {
        float3 position        : POSITION0;
        float2 texCoord        : TEXCOORD0;
        float3 normal        : NORMAL0;
        float3 binormal     : BINORMAL0;   
        float3 tangent        : TANGENT0;
    };

    struct VertexShaderOutput
    {
        float4 position            : POSITION0;
        float2 texCoord            : TEXCOORD0;
        float3 directionToLight    : TEXCOORD1;
        float3 viewDirection    : TEXCOORD2;
        float3x3 tangentToWorld    : TEXCOORD3;
    };

    VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
    {
        VertexShaderOutput output = (VertexShaderOutput)0;
       
        float4x4 wvp = mul(mul(World, View), Projection);
       
        output.position = mul(float4(input.position, 1.0f), wvp);
        float4 worldPosition = mul(float4(input.position, 1.0f), World);
       
        output.directionToLight = lightPosition - worldPosition;
        output.viewDirection = cameraPosition - worldPosition;
       
        output.tangentToWorld[0] = mul(input.tangent,   World);
        output.tangentToWorld[1] = mul(input.binormal,  World);
        output.tangentToWorld[2] = mul(input.normal,    World);
       
        output.texCoord = input.texCoord;
       
        return ( output );
    }

    float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
    {
        input.directionToLight = normalize(input.directionToLight);
        input.viewDirection = normalize(input.viewDirection);
       
        float3 normalFromMap = normalize(tex2D(NormalTextureSampler, input.texCoord).rgb * 2.0f - 1.0f);
        normalFromMap = mul(normalFromMap, input.tangentToWorld);
        normalFromMap = normalize(normalFromMap);
       
        //Diffuse
        float4 diffuseTexture = tex2D(DiffuseTextureSampler, input.texCoord);
        float nDotL = saturate( dot(normalFromMap, input.directionToLight));
        float4 diffuse = (2 * diffuseLightColor * nDotL);
       
        //Specular
        float4 SpecularTexture = tex2D(SpecularTextureSampler, input.texCoord);
        float3 reflectedLight = reflect(-input.directionToLight, normalFromMap);
        float rDotV = saturate(dot(reflectedLight, input.viewDirection));
        float4 specular = 4 * SpecularTexture * specularLightColor * pow(rDotV, specularPower);
       
        float4 emissive = tex2D(EmissiveTextureSampler, input.texCoord);

        return ((ambientLightColor) + diffuse + specular) * diffuseTexture + (2* emissive);
    }

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



  • 3/10/2008 4:42 PM In reply to

    Re: Gears of War in XNA

    Hi,
    Thanks for all the posts, but I still haven't figured out where the problem is. I think that it has to do with the tangent space. Here are two screenshots where you can see the problem and the source code. I will continue searching for a solution, and if I can manage to find one I will post it.

    Up to now I know that:
    1. It is not related to calculating the lightDirection in the vertex shader.
    2. It's not a problem with the model, because I have tried it with other models and the same thing happens.

    float4x4 World;
    float4x4 View;
    float4x4 Projection;

    float3 cameraPosition;

    //light properties
    float3 lightPosition;
    float4 ambientLightColor;
    float4 diffuseLightColor;
    float4 specularLightColor;

    //material properties
    float specularPower = 16;
    float specularIntensity = 1;


    texture2D Texture;
    texture2D NormalMap;
    texture2D EmissiveMap;
    texture2D SpecularMap;

    sampler2D DiffuseTextureSampler = sampler_state
    {
        Texture = <Texture>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D NormalTextureSampler = sampler_state
    {
        Texture = <NormalMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D EmissiveTextureSampler = sampler_state
    {
        Texture = <EmissiveMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };

    sampler2D SpecularTextureSampler = sampler_state
    {
        Texture = <SpecularMap>;
        MinFilter = linear;
        MagFilter = linear;
        MipFilter = linear;
    };


    struct VertexShaderInput
    {
        float3 position        : POSITION0;
        float2 texCoord        : TEXCOORD0;
        float3 normal        : NORMAL0;
        float3 binormal     : BINORMAL0;   
        float3 tangent        : TANGENT0;
    };

    struct VertexShaderOutput
    {
        float4 position            : POSITION0;
        float2 texCoord            : TEXCOORD0;
        float3 directionToLight    : TEXCOORD1;
        float3 viewDirection    : TEXCOORD2;
        float3x3 tangentToWorld    : TEXCOORD3;
    };

    VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
    {
        VertexShaderOutput output = (VertexShaderOutput)0;
       
        float4x4 wvp = mul(mul(World, View), Projection);
       
        output.position = mul(float4(input.position, 1.0f), wvp);
        float4 worldPosition = mul(float4(input.position, 1.0f), World);
       
        output.directionToLight = lightPosition - worldPosition;
        output.viewDirection =  cameraPosition - worldPosition;
       
        output.tangentToWorld[0] = mul(input.tangent,   World);
        output.tangentToWorld[1] = mul(input.binormal,  World);
        output.tangentToWorld[2] = mul(input.normal,    World);
       
        output.texCoord = input.texCoord;
       
        return ( output );
    }

    float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
    {
        input.directionToLight = normalize(input.directionToLight);
        input.viewDirection = normalize(input.viewDirection);
       
        float3 normalFromMap = normalize(tex2D(NormalTextureSampler, input.texCoord).rgb * 2.0f - 1.0f);
        normalFromMap = mul(normalFromMap, input.tangentToWorld);
        normalFromMap = normalize(normalFromMap);
       
        //Diffuse
        float4 diffuseTexture = tex2D(DiffuseTextureSampler, input.texCoord);
        float nDotL = saturate( dot(normalFromMap, input.directionToLight));
        float4 diffuse = (2 * diffuseLightColor * nDotL);
       
        //Specular
        float4 SpecularTexture = tex2D(SpecularTextureSampler, input.texCoord);
        float3 reflectedLight = reflect(-input.directionToLight, normalFromMap);
        float rDotV = saturate(dot(reflectedLight, input.viewDirection));
        float4 specular = 4 * SpecularTexture * specularLightColor * pow(rDotV, specularPower);
       
        float4 emissive = tex2D(EmissiveTextureSampler, input.texCoord);

        return ((ambientLightColor) + diffuse + specular) * diffuseTexture + (2* emissive);
    }

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


  • 3/10/2008 11:37 PM In reply to

    Re: Gears of War in XNA

    FYI, I removed a post about how to rip such models... this thread is close to the edge due to use of copyright material as it is... any discussion of where to get, how to rip, or distributing these models will ensure it gets deleted.

    Also no debates on legal issues... you know what will happen. So keep the replies on topic to fixing the OP question.

    Play Kissy Poo - a game for 4 year olds on Xbox and windows
    The ZBuffer
    News and information for XNA
      Follow The Zman on twitter, Email me
        Please read the forum FAQs - Bug/Feature reporting
          Don't forget to mark good answers and good playtest feedback when you see it!!!
  • 3/11/2008 12:46 PM In reply to

    Re: Gears of War in XNA

    Hi,
    I have downloaded this material from Epic Games Web Site, For example, you can download Marcus in max format from:
    http://udn.epicgames.com/Three/GearsMods.html

    You  can download 3 "Unreal Tournament 3" models from Epic Games Web Site too. I didn't rip this model.

  • 3/12/2008 12:38 PM In reply to

    Re: Gears of War in XNA

    After looking at the model it appears then half of the model is too light at the front and the same half of the model is too dark at the back. I would assume, that the model was created as a half model, then copied and mirrored to form a whole. So the normals of the copied and mirrored part of the model might be inverted, leading to the messed up lighting. I would suggest that you load the model in the 3D modelling tool you use and check that the normals on both side of the model point into the same direction (to the outside) and then export it again.
  • 3/13/2008 7:11 AM In reply to

    Re: Gears of War in XNA

    you can se the model with vertex lghting, so that is not the problem



    Does anyone have any more ideas?

  • 3/13/2008 9:40 AM In reply to

    Re: Gears of War in XNA

    As Jon mentioned, hard seams like that are usually down to the tangent frame calculation. In this case your model has mirrored UV coordinates so the model processor is generating mirrored tangent frames. One way of dealing with this is storing the sign of the tangent frame in each vertex (a 4 component tangent with the sign in .w) then you can mirror the tangent in your vertex shader (search for more info). This does mean that you will have to generate the tangents yourself in a custom model processor or using some other tool (Max perhaps).
Page 1 of 1 (11 items) Previous Next
var gDomain='m.webtrends.com'; var gDcsId='dcschd84w10000w4lw9hcqmsz_8n3x'; var gTrackEvents=1; var gFpc='WT_FPC'; /*<\/scr"+"ipt>");} /*]]>*/
DCSIMG