//vertex shader:
float3 fvLightPosition;
float3 fvEyePosition;
float4x4 matView;
float4x4 matViewProjection;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 Normal : NORMAL0;//通常只需要两个向量,因为另一个可以叉乘得到
float3 Binormal : BINORMAL0;
float3 Tangent : TANGENT0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection: TEXCOORD2;
};
VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;
Output.Position = mul( Input.Position, matViewProjection );
Output.Texcoord = Input.Texcoord;
float3 fvObjectPosition = mul( Input.Position, matView );
float3 fvViewDirection = fvEyePosition - fvObjectPosition;
float3 fvLightDirection = fvLightPosition - fvObjectPosition;
float3 fvNormal = mul( Input.Normal, matView );
float3 fvTangent = mul( Input.Tangent, matView );
float3 fvBinormal = mul( Input.Binormal, matView );//通常输入只需要nornal和tangent,binormal可以由两者叉乘得到
//fvBinormal = cross( fvNormal, fvTangent );
//将视方向和光线方向都转换到法线空间(或者称切线空间)
Output.ViewDirection.x = dot( fvTangent, fvViewDirection );
Output.ViewDirection.y = dot( fvBinormal, fvViewDirection );
Output.ViewDirection.z = dot( fvNormal, fvViewDirection );
Output.LightDirection.x = dot( fvTangent, fvLightDirection );
Output.LightDirection.y = dot( fvBinormal, fvLightDirection );
Output.LightDirection.z = dot( fvNormal, fvLightDirection );
return( Output );
}
//Pixel Shader
float4 fvAmbient;
float4 fvSpecular;
float4 fvDiffuse;
float fSpecularPower;
sampler2D baseMap;
sampler2D bumpMap;
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection: TEXCOORD2;
};
float4 ps_main( PS_INPUT Input ) : COLOR0
{
float3 fvLightDirection = normalize( Input.LightDirection );
float3 fvNormal = normalize( ( tex2D( bumpMap, Input.Texcoord ).xyz * 2.0f ) - 1.0f );
float fNDotL = dot( fvNormal, fvLightDirection );
float3 fvReflection = normalize( ( ( 2.0f * fvNormal ) * ( fNDotL ) ) - fvLightDirection );
float3 fvViewDirection = normalize( Input.ViewDirection );
float fRDotV = max( 0.0f, dot( fvReflection, fvViewDirection ) );
float4 fvBaseColor = tex2D( baseMap, Input.Texcoord );
float4 fvTotalAmbient = fvAmbient * fvBaseColor;
float4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor;
float4 fvTotalSpecular = fvSpecular * pow( fRDotV, fSpecularPower );
return( saturate( fvTotalAmbient + fvTotalDiffuse + fvTotalSpecular ) );
}