Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Here's a button I exported from Blender into a .x format: The Button after a Blender-Render

Now here it is in the game with BasicEffect applied to everything: Button with BasicEffect Applied

And now with my custom shader: Hmmm, that's not supposed to do that

And there's the problem. While the surrrounding environment is much brighter (I will get around to doing something about that btw), the button isn't. I'm using the vertex shader to do the lighting calculations. Sharp-eyed observers will notice that the texture is still slightly visible, but that's just ambient lighting. I have no specular lighting, just ambient + diffuse. So I guessed if lighting = ambient, then diffuse must be 0.

Here's my diffuse code:

float4 CombineDiffuseLights(float3 Normal, float3 Position3D)
{
    float4 lightColour = (0,0,0,0);
    for (int i = 0; i < NumberOfLights; i++)
    {
        float3 LightDirection = normalize(LightPosition[i] - Position3D);
        float DiffuseIntensity = saturate(dot(LightDirection, Normal));  //Where I suspect the problem lies
        lightColour += DiffuseIntensity * DiffuseColour * AttenuationPerLight(Position3D, LightPosition[i]);
    }
    lightColour.a = 1;
    return lightColour;
}

For the record:

  • Normal = mul(input.Normal, World);
  • Position3D = mul(input.Position, World);
  • DiffuseColour = (1,1,1,1);
  • Everything in the environment is using the same (vertex) shader
  • All normals are the right way around (CULLMODE = CCW;)
  • All LightPositions are going in with correct values

I've also noticed that if I manually set DiffuseIntensity = 1; this happens: Bright, depthless, but relatively OK

Besides the retina-searing brightness, it's proportionally the right shade compared to the environment, but there's no depth (duh, it's all 1). So why on earth is DiffuseIntensity = saturate(dot(LightDirection, Normal)); giving me problems? It's a pretty standard way of finding a diffuse value isn't it? Is it doing something that I'm not aware of or is it a case of 'HLSL: You're doing it wrong!'? Normally I'd have some clue but I am totally stuck on this one.

share|improve this question

1 Answer 1

up vote 3 down vote accepted

Found it. After days of debugging with PIX, looking through assembly code and reviewing all of my old code samples, it turned out that it wasn't anything in my diffuse code that was wrong, just one of the parameters I passed through. I said I was using:

Normal = mul(input.Normal, World);

but I was assuming that I hadn't non-uniformly scaled anything. As it turns out I should have used:

Normal = mul(input.Normal, WorldInverseTranspose);

It took me a couple of minutes to work it out, but I eventally found that I was using non-uniform scaling, and I was using it on the exact objects that were screwing up. At least now I know what a non-uniformly scaled object looks like without Matrix.Inverse(Matrix.Transpose(objectWorldMatrix)) applied to it.

It's always the little things isn't it...

share|improve this answer
    
Then accept your own answer by hitting the checkmark beside it. –  Nick Wiggill Dec 31 '12 at 13:58
    
@NickWiggill you can't accept your own answer for about two days. –  ashes999 Dec 31 '12 at 14:37
    
@ashes999 I am reinformed. Thank you. –  Nick Wiggill Dec 31 '12 at 14:39
    
@Nick I was kinda surprised to find that I had to wait 4 hours to answer, but it's done now. –  MetaReference Dec 31 '12 at 16:48
    
@MetaReference it's a precaution in place to prevent people just asking/answering their own questions just to get more rep. –  ashes999 Dec 31 '12 at 17:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.