Original Post
I've been working on a program to render MD5Mesh models from Doom 3, but there seems to be a problem with my view / half vector calculations leading to wrong specular values. Here's how I set up the view matrix:
And here's how I retrieve the camera's position to pass to the shader:
And here's my vertex program (Cg):
And my debug fragment program returning the specular value (Cg):
Any ideas?..
void camera::apply_transformation()
{
ViewMatrix = translation_matrix(Vec3(0, 0, -Zoom)) * translation_matrix(Vec3(TranslationX, TranslationY, 0)) * rotation_matrix_deg(RotationX, Vec3(1, 0, 0)) * rotation_matrix_deg(RotationY, Vec3(0, 1, 0));
}
And here's how I retrieve the camera's position to pass to the shader:
float3 camera::position()
{
Vec4 Result(TranslationX, TranslationY, -Zoom, 1);
Mat4 OrientationMatrix = rotation_matrix_deg(RotationX, Vec3(1, 0, 0)) * rotation_matrix_deg(RotationY, Vec3(0, 1, 0));
Result = Result * OrientationMatrix;
return float3(Result[0], Result[1], Result[2]);
}
And here's my vertex program (Cg):
float4 main(uniform float4x4 WorldMatrix,
uniform float4x4 WorldViewMatrix,
uniform float4x4 WorldViewProjectionMatrix,
uniform float3 LightPosition,
uniform float3 CameraPosition,
in float4 Position : ATTR0,
in float3 Normal : ATTR1,
in float4 Tangent : ATTR2,
in float2 TexCoord : ATTR3,
out float4 oPosition : TEXCOORD0,
out float3 oNormal : TEXCOORD1,
out float4 oTangent : TEXCOORD2,
out float2 oTexCoord : TEXCOORD3,
out float3 TangentSpaceLightVector : TEXCOORD4,
out float3 TangentSpaceHalfVector : TEXCOORD5,
out float3 oViewDir : TEXCOORD6,
out float3 oCameraPosition : TEXCOORD7) : HPOS
{
oPosition = mul(WorldMatrix, Position);
oNormal = normalize(mul(WorldMatrix, float4(Normal, 1)).xyz);
oTangent = normalize(float4(mul(WorldMatrix, float4(Tangent.xyz, 1)).xyz, Tangent.w));
oTexCoord = TexCoord;
float3 BiTangent = normalize(cross(oNormal, oTangent.xyz));// * oTangent.w);
float3x3 TBN;
TBN[0] = oTangent.xyz;
TBN[1] = BiTangent;
TBN[2] = oNormal;
float3 LightVector = LightPosition - oPosition;
float3 ViewDir = CameraPosition - oPosition;
oViewDir = mul(TBN, ViewDir);
oCameraPosition = CameraPosition;
float3 HalfVector = normalize(LightVector + ViewDir);
TangentSpaceLightVector = mul(TBN, LightVector);
TangentSpaceHalfVector = mul(TBN, HalfVector);
return mul(WorldViewProjectionMatrix, Position);
}
And my debug fragment program returning the specular value (Cg):
float4 main(in float4 Position : TEXCOORD0,
in float3 Normal : TEXCOORD1,
in float4 Tangent : TEXCOORD2,
in float2 TexCoord : TEXCOORD3,
in float3 TangentSpaceLightVector : TEXCOORD4,
in float3 TangentSpaceHalfVector : TEXCOORD5,
in float3 ViewDir : TEXCOORD6,
in float3 InCameraPosition : TEXCOORD7,
uniform sampler2D DiffuseTexture : TEXUNIT0,
uniform sampler2D NormalMap : TEXUNIT1,
uniform sampler2D HeightMap : TEXUNIT2,
uniform sampler2D SpecularMap : TEXUNIT3) : COLOR
{
float4 Diffuse = tex2D(DiffuseTexture, TexCoord);
float3 PerPixelNormal = h3tex2D(NormalMap, TexCoord).xyz*2-1;
float4 SpecularExponent = tex2D(SpecularMap, TexCoord);
float Height = tex2D(HeightMap, TexCoord).x;
float4 SpecularColor = float4(1);
float3 LightVector = normalize(TangentSpaceLightVector);
float3 HalfVector = normalize(TangentSpaceHalfVector);
float Dot = saturate(dot(PerPixelNormal, LightVector));
float Specular = pow(saturate(dot(PerPixelNormal, HalfVector)), 64);
return Specular;
}
Any ideas?..