We've implemented our own normal + specular shader and it shows up real strange:
Interestingly, when the sun direction in tangent space is _not_ normalized within the pixel shader, the diffuse component shows up smoothly, the specular is still "flat". However, that can't be right.
The mesh is converted to tangents using:
Code: Select all
getMeshManipulator()->createMeshWithTangents(mesh->getMesh(0), false, false, false);
Here's the used shader code, for insight:
Vertex:
Code: Select all
float3 fvSunDir;
float3 fvEyePosition;
float4x4 matWorld;
float4x4 ModelViewProjectionMatrix;
float4x4 rotObjInv;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 Normal : NORMAL0;
float4 tangent : TEXCOORD1;
float4 binormal : TEXCOORD2;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 SunTangent : TEXCOORD2;
};
VS_OUTPUT main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul(Input.Position, ModelViewProjectionMatrix);
Output.Texcoord = Input.Texcoord;
float3x3 TBNMatrix = float3x3(
normalize(Input.tangent.xyz),
normalize(Input.binormal.xyz),
normalize(Input.Normal));
Output.SunDirection = (mul((fvSunDir), rotObjInv));
Output.SunTangent = (mul(TBNMatrix, Output.SunDirection));
float4 fvObjectPosition = mul( Input.Position, matWorld );
Output.ViewDirection = mul(TBNMatrix, fvEyePosition -fvObjectPosition);
return( Output );
}
Code: Select all
float4 fvAmbient;
float4 fvSpecular;
float4 fvDiffuse;
float4 f4SunColor;
float fSunIntensity;
float fSpecularPower;
float fShininess;
sampler2D tex0; // diffuse
sampler2D tex1; // spec
sampler2D tex2; // normal
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 SunTangent : TEXCOORD2;
};
float4 main( PS_INPUT Input ) : COLOR0
{
float3 fvViewDirection = normalize(Input.ViewDirection);
float3 fvSunTangent = normalize(Input.SunTangent);
// Textures
float4 fvBaseColor = tex2D(tex0, Input.Texcoord);
float4 fvSpecularColor = tex2D(tex1, Input.Texcoord);
float3 fvNormalMapped = normalize((2.0f * tex2D(tex2, Input.Texcoord).rgb - 1.0f));
// Sun Stuff
float fNLSun = saturate(dot(fvNormalMapped, fvSunTangent ));
float fRDotV2 = 0;
if(fNLSun > 0.f)
{
float3 half = normalize((fvSunTangent + fvViewDirection) * 0.5f);
fRDotV2 = saturate(dot(fvNormalMapped, half));
}
float my = saturate(fShininess * 0.001 + 0.4);
float my2 = fSpecularPower * 0.001 + 150;
float4 spec = fvSpecular + fvSpecularColor;
float4 fvTotalAmbient = fvAmbient;
float4 fvTotalDiffuse = fvDiffuse * saturate(fNLSun * fSunIntensity);
float4 fvTotalSpecular = fShininess * spec * pow(fRDotV2 * fSunIntensity, fSpecularPower);
return(saturate(fvBaseColor * (fvTotalAmbient + fvTotalDiffuse) + fvTotalSpecular));
}