// Tweakables:
static const float AmbientIntensity = 1.0f; // The intensity of the ambient light.
static const float DiffuseIntensity = 1.0f; // The intensity of the diffuse light.
static const float SpecularIntensity = 1.0f; // The intensity of the specular light.
static const float SpecularPower = 8.0f; // The specular power. Used as 'glossyness' factor.
static const float4 SunColor = {0.0f, 0.0f, 0.0f, 0.0f}; // Color vector of the sunlight.
float water_height;
// Application fed data:
const float4x4 matWorldViewProj; // World*view*projection matrix.
const float4x4 matWorld; // World matrix.
const float4 vecAmbient; // Ambient color.
const float4 vecSunDir; // Sun light direction vector.
const float4 vecViewPos; // View position.
float3x3 matTangent; // hint for the engine to create tangents in TEXCOORD2
texture mtlSkin1;
sampler ColorMapSampler = sampler_state // Color map sampler.
{
Texture = <mtlSkin1>;
MipFilter = Linear; // required for mipmapping
};
texture mtlSkin2; // Normal map.
sampler NormalMapSampler = sampler_state // Normal map sampler.
{
Texture = <mtlSkin2>;
MipFilter = None; // a normal map usually has no mipmaps
};
// Vertex Shader:
void NormalMapVS( in float4 InPos: POSITION,
in float3 InNormal: NORMAL,
in float3 InTex: TEXCOORD0,
in float4 InTangent: TEXCOORD2,
out float4 OutPos: POSITION,
out float3 OutTex: TEXCOORD0,
out float3 OutViewDir: TEXCOORD1,
out float3 OutSunDir: TEXCOORD2)
{
// Transform the vertex from object space to clip space:
OutPos = mul(InPos, matWorldViewProj);
// Pass the texture coordinate to the pixel shader:
OutTex = InTex;
OutTex.z = mul(InPos,matWorld).y;
// Compute 3x3 matrix to transform from world space to tangent space:
matTangent[0] = mul(InTangent.xyz, matWorld);
matTangent[1] = mul(cross(InTangent.xyz, InNormal)*InTangent.w, matWorld);
matTangent[2] = mul(InNormal, matWorld);
// Calculate the view direction vector in tangent space:
OutViewDir = normalize(mul(matTangent, (vecViewPos - mul(InPos,matWorld))));
// Calculate the light direction vector in tangent space:
OutSunDir = normalize(mul(matTangent, -vecSunDir));
}
// Pixel Shader:
float4 NormalMapPS(
in float3 InTex: TEXCOORD0,
in float3 InViewDir: TEXCOORD1,
in float3 InSunDir: TEXCOORD2): COLOR
{
clip(InTex.z);//water_height_var
// Read the normal from the normal map and convert from [0..1] to [-1..1] range
float3 BumpNormal = tex2D(NormalMapSampler, InTex)*2 - 1;
// Calculate the ambient term:
float4 Ambient = AmbientIntensity * vecAmbient;
// Calculate the diffuse term:
float4 Diffuse = DiffuseIntensity * SunColor * saturate(dot(InSunDir, BumpNormal));
// Calculate the reflection vector:
float3 R = normalize(2 * dot(BumpNormal, InSunDir) * BumpNormal - InSunDir);
// Calculate the specular term:
InViewDir = normalize(InViewDir);
float Specular = pow(saturate(dot(R, InViewDir)), SpecularPower) * SpecularIntensity;
// Fetch the pixel color from the color map:
float4 Color = tex2D(ColorMapSampler, InTex);
// Calculate final color:
return (Ambient + Diffuse + Specular) * Color;
}
// Technique:
technique NormalMapTechnique
{
pass P0
{
VertexShader = compile vs_2_0 NormalMapVS();
PixelShader = compile ps_2_0 NormalMapPS();
}
}