Hi, recently I have begun to learn HLSL with my first three shaders being an implementation of a Phng shader for directional, point, and spotlight.
Next to begin using more advanced methods I tried to implement the same shader using Tangent space coordinates but had problems, hence I stripped out the use of the normal map and tried the shader in rendermonkey using the same technique but using surface normals, the same problem occured.
Here is the original basic shader:
//VS
float4x4 matViewProjection;
float4x4 matWorld;
float4 vViewPosition;
float4 vDirLight;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float3 Norm: TEXCOORD0;
float2 Tex: TEXCOORD1;
float3 View: TEXCOORD2;
float3 Light: TEXCOORD3;
};
VS_OUTPUT vs_main( float4 inPos: POSITION,
float3 inNorm:NORMAL,
float2 inTex: TEXCOORD0 )
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
Out.Pos = mul(matViewProjection, inPos);
Out.Light = vDirLight;
Out.Tex = inTex;
float3 vPosWorld = normalize( mul( matWorld, inPos ) );
Out.View = normalize( vViewPosition - vPosWorld );
Out.Norm = normalize( mul( matWorld, inNorm ) );
return Out;
}
//PS
float fShinyness;
float4 colDiffuse;
float4 colSpecular;
float4 colAmbient;
float4 lightAmbient;
float4 lightDiffuse;
float4 lightSpecular;
float4 globalAmbient;
sampler Texture0;
float4 ps_main( float3 inNorm: TEXCOORD0,
float2 inTex: TEXCOORD1,
float3 inView: TEXCOORD2,
float3 inLight: TEXCOORD3 ) : COLOR
{
//normalize inputs
float3 vNormal = normalize(inNorm);
float3 vLight = -normalize(inLight);
float3 vView = normalize(inView);
//calc diffuse/specular
float fNormalDotLight = saturate ( dot(vNormal, vLight) );
float3 vLightReflect = 2.0*fNormalDotLight*vNormal - vLight;
float fViewDotReflect = saturate( dot(vView, vLightReflect) );
float4 fSpecIntensity = pow(fViewDotReflect, fShinyness);
float4 diffuse = fNormalDotLight * colDiffuse * lightDiffuse;
float4 specular = fSpecIntensity * colSpecular * lightSpecular;
float4 ambient = ( colAmbient * lightAmbient ) + globalAmbient;
return (ambient + diffuse) * tex2D(Texture0, inTex) + specular;
}
This shader workes fine:
The following is the shader in tangent space
//VS
float4x4 matViewProjection;
float4x4 matWorld;
float4 vViewPosition;
float4 vDirLight;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 Tex: TEXCOORD0;
float3 Norm: TEXCOORD1;
float3 Light: TEXCOORD2;
float3 View: TEXCOORD3;
};
VS_OUTPUT vs_main( float4 inPos: POSITION,
float3 inNorm:NORMAL,
float2 inTex: TEXCOORD0,
float3 inTang: TANGENT )
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
//output texture and position coordinates
Out.Pos = mul(matViewProjection, inPos);
Out.Tex = inTex;
float4 vPosWorld = mul( matWorld, inPos );
//generate tangent space vectors
float3x3 mToTangent;
mToTangent[0] = mul(inTang, (float3x3)matWorld) ;
mToTangent[2] = mul(inNorm, (float3x3)matWorld) ;
mToTangent[1] = cross(mToTangent[0], mToTangent[2]);
//calc light and eye vectors and projectors texture coordinates
float3 vLight = normalize(vDirLight - vPosWorld);
Out.Light = mul(mToTangent, vDirLight);
float3 vToEye = normalize(vViewPosition - vPosWorld);
Out.View = mul(mToTangent, vToEye);
Out.Norm = inNorm;
return Out;
}
//PS
float fShinyness;
float4 colDiffuse;
float4 colSpecular;
float4 colAmbient;
float4 lightAmbient;
float4 lightDiffuse;
float4 lightSpecular;
float4 globalAmbient;
sampler Texture0;
sampler Texture1;
float4 ps_main( float4 inPos: POSITION,
float2 inTex: TEXCOORD0,
float3 inNorm: TEXCOORD1,
float3 inLight: TEXCOORD2,
float3 inView: TEXCOORD3 ) : COLOR
{
//set inputs
//float3 vNormal = normalize( tex2D(Texture1, inTex).xyz );
float3 vNormal = normalize(inNorm);
float3 vLight = normalize(inLight);
float3 vView = normalize(inView);
//calc diffuse/specular
float fNormalDotLight = saturate ( dot(vNormal, vLight) );
float3 vLightReflect = 2.0*fNormalDotLight*vNormal - vLight;
float fViewDotReflect = saturate( dot(vView, vLightReflect) );
float4 fSpecIntensity = pow(fViewDotReflect, fShinyness);
float4 diffuse = fNormalDotLight * colDiffuse * lightDiffuse;
float4 specular = fSpecIntensity * colSpecular * lightSpecular;
float4 ambient = ( colAmbient * lightAmbient ) + globalAmbient;
return (ambient + diffuse) * tex2D(Texture0, inTex) + specular;
}
This shader seems to have inaccuracies with the reflection and has problems with the texture coordinates.
Any constructive help would be appreciated.
[Edited by - Coder on October 3, 2004 2:23:05 PM]