I've been messing around with a simple .fx shader that renders diffuse map, normal map and specular lighting from a single light source and have been getting some odd results. If I were to take a snapshot of it, it would look great, but whenever the camera changes oriantation the light direction seems to jump around. BUT, this only appears to happen when the framerate is dropping below 60 (like 58 fps). It appears as though the light source jumps around to various angles between frames making it flicker.
This is my draw call:
private void DrawModel2(Model m)
{
Matrix[] transforms = new Matrix[m.Bones.Count];
m.CopyAbsoluteBoneTransformsTo(transforms);
worldMatrix = transforms[0]
* Matrix.CreateTranslation(obstPos);
WVP.SetValue(worldMatrix * viewMatrix * projectionMatrix);
fx2.SetValue(worldMatrix);
fx3.SetValue(Matrix.Invert(viewMatrix));
fx4.SetValue(Matrix.Invert(Matrix.Transpose(worldMatrix)));
foreach (ModelMesh mesh in m.Meshes)
{
foreach (Effect effect in mesh.Effects)
{
mesh.Draw();
}
}
}
The EffectParameter assignments made in LoadContent():
metal.CurrentTechnique = metal.Techniques["NormalMapping_Spec"];
WVP = metal.Parameters["mWorldViewProjection"];
fx2 = metal.Parameters["mWorld"];
fx3 = metal.Parameters["mViewInverse"];
fx4 = metal.Parameters["mWorldInverseTranspose"];
And the relevant parts of the HLSL file:
float4 light1Direction: Light1Direction
<
> = {0.5, .8, .5, 0.00};
float4 light1Color: Light1Diffuse
<
> = {0.5, 0.5, 0.5, 1.0};
float4 light1SpecularColor: Light1Specular
<
string UIName = "Surface Specular";
> = {1.00, 0.96, 0.67, 0.00};
float light1SpecExpon: Light1SpecularPower <
string UIWidget = "slider";
float UIMin = 1.0;
float UIMax = 128.0;
float UIStep = 1.0;
string UIName = "Specular Power";
> = 45.0;
float4 ambiColor: AmbientColor
<
string UIName = "Ambient Light Color";
> = {0.2f, 0.2f, 0.2f, 1.0f};
float4 surfColor: SurfaceColor
<
string UIName = "Surface Color";
> = {1.0f, 1.0f, 1.0f, 1.0f};
texture txDiffuseMap: TextureColor;
texture txNormalMap: TextureNormal;
sampler2D samDiffuseMap = sampler_state
{
Texture = <txDiffuseMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
sampler2D samNormalMap = sampler_state
{
Texture = <txNormalMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
AddressU = Wrap;
AddressV = Wrap;
};
float4x4 mWorld: World;
float4x4 mViewInverse: ViewInverse;
float4x4 mWorldInverseTranspose: WorldInverseTranspose;
float4x4 mWorldViewProjection: WorldViewProjection;
//Removed Irrelevant Code here until we get to the PS math-------------
float4 PS_NormalMapping_Spec(VS_OUTPUT In, uniform float3 lightDirection, uniform float4 lightColor, uniform float4 specularColor, uniform float specularExponent): COLOR
{
float3 normal = tex2D(samNormalMap, In.TexCoord0.xy).xyz * 2.0 - 1.0;
float4 color = tex2D(samDiffuseMap, In.TexCoord0.xy);
float3 N = (In.worldNormal * normal.z) + (normal.x * In.worldBinormal) + (normal.y * In.worldTangent);
N = normalize(N);
float3 V = normalize(In.EyeVec);
float3 L = normalize(lightDirection);
float4 output = ambiColor * color;
output += lightColor * blinn(N, L, V, color*In.Diffuse, specularColor*color.a, specularExponent);
output.a = color.a * In.Diffuse.a;
return output;
}
//And the technique call-----------------------------
technique NormalMapping_Spec
{
pass Light1
{
VertexShader = compile vs_2_0 VS_NormalMapping();
PixelShader = compile ps_2_0 PS_NormalMapping_Spec(light1Direction,light1Color,light1SpecularColor,light1SpecExpon);
}
}
I know that's a lot of code, but I've tried tweaking EVERYTHING and still have this problem. I've even used some other shaders I found on the internet and they seem to all have the same problem when applying a normal map. Any help from someone proficient with shaders would be much appreciated.