Here is the shader I'm using now.
//////////////////////////////////////////////////////////////////////////////////////////////////
// File: ParallaxMapPointLight.fx
// Author: Chris Smith
// Date Created: 12/17/06
// Description: Renders a scene with parallax mapping from a point light
// Disclaimer: Use this however you want, but I am not responsible for anything
//////////////////////////////////////////////////////////////////////////////////////////////////
float4x4 WorldViewProj; //World * View * Projection Matrix
float4x4 World; //World matrix of object
float4 EyePos; //Position of eye in world space
float4 LightPos; //Light position in world space
float4 LightColor; //Color of the light
texture ColorMap; //Color texture
texture NormalMap; //Normal map texture
texture HeightMap; //Height map texture
float Falloff; // Distance until light begins to falloff
float Ambient; // Ambient amount of lighting
float DepthScale = 0.04f; //Depth of the parallax map
float Bias = 0.02f; //Bias of the parallax map
float scale;
sampler colorSampler = sampler_state
{
Texture = (ColorMap);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};
sampler normalSampler = sampler_state
{
Texture = (NormalMap);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};
sampler heightSampler = sampler_state
{
Texture = (HeightMap);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};
//////////////////////////////////////////////////////////////
//Structures
//////////////////////////////////////////////////////////////
//Application to vertex shader
struct A2V
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 TexCoord0 : TEXCOORD0;
float3 Tangent : TANGENT;
float3 Binormal : BINORMAL;
};
//Vertex shader to pixel shader
struct V2P
{
float4 Position : POSITION;
float2 TexCoord0 : TEXCOORD0;
float3 LightDir : TEXCOORD1;
float3 ViewDir : TEXCOORD2;
};
//////////////////////////////////////////////////////////////
//Vertex Shader
//////////////////////////////////////////////////////////////
void VS( in A2V IN, out V2P OUT )
{
IN.Position.xyz *= scale;
//Transform the position from view space to homogeneous projection space
OUT.Position = mul(IN.Position, WorldViewProj);
//Compute world space position
float4 WorldPos = mul(IN.Position, World);
//Calculate Binormal and set Tangent Binormal and Normal matrix
float3x3 TBNMatrix = mul(float3x3(IN.Binormal, IN.Tangent , IN.Normal), (float3x3)World);
//Compute light direction
OUT.LightDir = LightPos - WorldPos;
//Compute light direction * TBN Matrix
OUT.LightDir = mul(TBNMatrix, OUT.LightDir);
//Compute view direction * TBN Matrix
OUT.ViewDir = mul(TBNMatrix, EyePos - WorldPos);
//Copy the texture coordinate as is
OUT.TexCoord0 = IN.TexCoord0;
}
//////////////////////////////////////////////////////////////
//Pixel Shader
//////////////////////////////////////////////////////////////
float4 PS( in V2P IN ) : COLOR0
{
IN.ViewDir = normalize(IN.ViewDir);
//Determine the height of this pixel
float Height = DepthScale * tex2D(heightSampler, IN.TexCoord0) - Bias;
//Compute the new texture coorddinate to use
float2 TexCorrected = Height * IN.ViewDir + IN.TexCoord0;
//calculate the color and the normal
float4 Color = tex2D(colorSampler, TexCorrected);
//Uncompress the normal map
float3 Normal = 2.0f * tex2D(normalSampler, TexCorrected).rgb - 1.0f;
//Pixel to light vector
float LenSq = dot( IN.LightDir, IN.LightDir );
IN.LightDir = normalize( IN.LightDir );
//Compute the light's attenuation
float Attn = min(( Falloff * Falloff ) / LenSq, 1.0f);
//Compute the diffuse lighting amount
float Diffuse = Attn * saturate(dot(Normal, IN.LightDir));
//Lighting amount * Texture Color * Light Color
return Color = (Diffuse + Ambient) * Color * LightColor;
}
//////////////////////////////////////////////////////////////
//Technique
//////////////////////////////////////////////////////////////
technique ParallaxMapPointLight
{
pass p0
{
vertexshader = compile vs_2_0 VS();
pixelshader = compile ps_2_0 PS();
}
}






