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

[SOLVED]Odd HLSL Normal mapping issue

Last post 19/06/2009 20:28 by Zazu Yen. 1 replies.
  • 19/06/2009 0:22

    [SOLVED]Odd HLSL Normal mapping issue

    Maybe someone here can help me with this, it's driving me nuts.

    I've been working on a fairly simple HLSL shader and everything is working pretty well except for one problem, I've spent hours tinkering with the code and stepping through disassembly in PIX with no luck. The normal map looks fine from the 'front' of the sample sphere, but it appears to slowly invert as it wraps around the sphere, so that in the 'back' of the sphere what should be sticking out is sticking in and vice-versa. Here is a sample image:

    On the left is the front of the sphere and is the way it's supposed to look, on the right the sphere has been turned about 180 degrees. You can see that the grout on the right image is actually looking higher than the bricks.
    http://www.twilightfair.com/otherstuff/images/NormalExamples.jpg

    This would seem to be a simple problem, a missing transition or an out of order matrix multiplication, but I've had no luck finding it. I need some experienced eyes to take a look at the code and point out my fallacy. Here is the HLSL shader with all the extras pulled out (spectral mapping, spectral highlights, environment mapping, etc. etc.) It still has the same problem.


    Relevant C# code:
            Matrix marbleWorld = Matrix.CreateFromYawPitchRoll(ballRotation.Y, ballRotation.X, ballRotation.Z); 
            effect.Parameters["WorldTransform"].SetValue(marbleWorld); 
            effect.Parameters["CameraTransform"].SetValue(marbleWorld * camera.View * camera.Projection); 
            effect.Parameters["DirectionalLightDirection"].SetValue(new Vector3(1.0f, -1.0f, 0.5f)); 
            effect.Parameters["DirectionalLightColor"].SetValue(new Vector4(0.5f, 0.5f, 0.5f, 1.0f)); 


    HLSL code:
    ////////////////////////////////////////////////// 
    //  Normal debugging shader 
    ////////////////////////////////////////////////// 
     
    struct VertexIn 
        float4 position  : POSITION0; 
        float2 texCoords : TEXCOORD0; 
        float3 normal    : NORMAL0;     
        float3 tangent   : TANGENT0; 
        float3 binormal  : BINORMAL0; 
    }; 
     
    struct VertexToPixelBuggedNormal 
        float4 position      : POSITION;     
        float2 texCoords     : TEXCOORD0; 
        float3 viewVector    : TEXCOORD1; 
        float3 normal        : TEXCOORD2; 
         
        float3x3 tangentToWorld : TEXCOORD3; 
    }; 
     
    VertexToPixelBuggedNormal BuggedNormalVertexShader(VertexIn input) 
        VertexToPixelBuggedNormal output = (VertexToPixelBuggedNormal)0; 
     
        output.position = mul(input.position, CameraTransform); 
         
        output.texCoords = input.texCoords; 
         
        output.normal = normalize(mul(float4(input.normal,1.0f), WorldTransform)); 
         
        output.viewVector = -(DirectionalLightDirection.xyz*50) - mul(input.position, WorldTransform); 
         
        output.tangentToWorld[0] = mul(float4(input.tangent,1.0f),WorldTransform).xyz; 
        output.tangentToWorld[1] = mul(float4(input.binormal,1.0f),WorldTransform).xyz; 
        output.tangentToWorld[2] = mul(float4(input.normal,1.0f), WorldTransform).xyz; 
                 
        return output; 
     
    PixelToFrame BuggedNormalPixelShader(VertexToPixelBuggedNormal input) 
        PixelToFrame output = (PixelToFrame)0;         
     
        // clean up our inputs a bit 
        input.viewVector = normalize(input.viewVector); 
     
        // bump map 
        float3 bumpNorm = (2 * (tex2D(BumpSampler, input.texCoords).rgb-0.5f)); 
        bumpNorm = normalize(mul(bumpNorm,input.tangentToWorld)); 
             
        // directional light 
        float4 DirectionalLighting = (dot(bumpNorm, input.viewVector)) * DirectionalLightColor; 
     
        // base color     
        float4 baseColor = tex2D(TextureSampler, input.texCoords); 
     
        // adjust for lighting 
        baseColor.xyz *= saturate(DirectionalLighting + AmbientColor).xyz; 
         
        output.Color = baseColor; 
     
        return output;  
     
    technique BuggedNormal 
        pass Pass0 
        { 
             VertexShader = compile vs_2_0 BuggedNormalVertexShader(); 
             PixelShader = compile ps_2_0 BuggedNormalPixelShader(); 
        } 
     

    Thanks for any help you can offer!
    Code is my medium
    Follow my game development experiences with XNA at http://zenandcode.blogspot.com/
  • 19/06/2009 20:28 In reply to

    [SOLVED]Re: Odd HLSL Normal mapping issue

    Well, the shader is fine. The meshes I was using had no TBN data so the normals were not getting translated into model space correctly. I don't know why I didn't recognize the default data in the tangent, normal, binormal input registers in PIX.

    Let this be a hard lesson learned, always check the validity of your starting data when things appear to be going wrong for no reason! At least my shaders were, in fact, fine all along.
    Code is my medium
    Follow my game development experiences with XNA at http://zenandcode.blogspot.com/
Page 1 of 1 (2 items) Previous Next