Evolved - Multipass Normal Mapping Shader. Up to 6 lights and 1 flashlight.
//====================================================
// Normal Mapping 2.0
//====================================================
// By EVOLVED
// www.evolved-software.com
//====================================================
//--------------
// un-tweaks
//--------------
matrix WorldVP:WorldViewProjection;
matrix World:World;
matrix ViewInv:ViewInverse;
//--------------
// tweaks
//--------------
float3 Ambient={0.1f,0.1f,0.1f};
float3 LightPosition_1={0.0f,50.0f,0.0f};
float3 LightColor_1={1.0f,1.0f,1.0f};
float LightRange_1=55.0f;
float3 LightPosition_2={50.0f,50.0f,0.0f};
float3 LightColor_2={1.0f,0.0f,0.0f};
float LightRange_2=55.0f;
float3 LightPosition_3= {100.0f,50.0f,0.0f};
float3 LightColor_3={0.0f,1.0f,0.0f};
float LightRange_3=55.0f;
float3 LightPosition_4={150.0f,50.0f,0.0f};
float3 LightColor_4={0.0f,0.0f,1.0f};
float LightRange_4=55.0f;
float3 LightPosition_5={0.0f,50.0f,50.0f};
float3 LightColor_5={1.0f,1.0f,1.0f};
float LightRange_5=55.0f;
float3 LightPosition_6={50.0f,50.0f,50.0f};
float3 LightColor_6={1.0f,0.0f,0.0f};
float LightRange_6=55.0f;
float3 FLightPosition={150.0f,150.0f,0.0f};
float FLightRange=1000.0f;
float3x3 FLightAngle;
float BrightNess=1.0f;
float SpecularPow=16.0f;
float Alpha=1.0f;
//--------------
// Textures
//--------------
texture BaseTX <string Name="";>;
sampler2D Base = sampler_state
{
texture = <BaseTX>;
};
texture NormalTX <string Name="";>;
sampler2D Normal = sampler_state
{
texture = <NormalTX>;
};
texture CubeLightTX <string Name = "";>;
sampler CubeLight = sampler_state
{
Texture = <CubeLightTX>;
};
//--------------
// structs
//--------------
struct input
{
float4 Pos:POSITION;
float2 UV:TEXCOORD;
float3 Normal:NORMAL;
float3 Tangent:TANGENT;
float3 Binormal:BINORMAL;
};
struct output
{
float4 OPos:POSITION;
float2 Tex:TEXCOORD0;
float3 LightVec:TEXCOORD1;
float3 Attenuation:TEXCOORD2;
float3 ViewVec:TEXCOORD3;
float3 CubeLight:TEXCOORD4;
};
//--------------
// vertex shader
//--------------
output VS(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
OUT.LightVec=0;
OUT.Attenuation=0;
OUT.ViewVec=0;
OUT.CubeLight=0;
return OUT;
}
output VS_L1(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_1-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_1;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_L2(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_2-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_2;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_L3(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_3-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_3;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_L4(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_4-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_4;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_L5(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_5-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_5;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_L6(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=LightPosition_6-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange_6;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=0;
return OUT;
}
output VS_FL(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV;
float3x3 TBN={IN.Tangent,IN.Binormal,IN.Normal};
TBN=transpose(mul(TBN,World));
float3 WPos=mul(IN.Pos,World);
float3 LightPos=FLightPosition-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/FLightRange;
OUT.ViewVec=mul(ViewPos,TBN);
OUT.CubeLight=mul(FLightAngle,-LightPos);
return OUT;
}
//--------------
// pixel shader
//--------------
float4 PS(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
return float4(Texture*Ambient,Alpha);
}
float4 PS_L1(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_1;
return float4(Texture*((Normal*Light)+Ambient),Alpha);
}
float4 PS_L2(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_2;
return float4(Texture*(Normal*Light),Alpha);
}
float4 PS_L3(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_3;
return float4(Texture*(Normal*Light),Alpha);
}
float4 PS_L4(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_4;
return float4(Texture*(Normal*Light),Alpha);
}
float4 PS_L5(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_5;
return float4(Texture*(Normal*Light),Alpha);
}
float4 PS_L6(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*LightColor_6;
return float4(Texture*(Normal*Light),Alpha);
}
float4 PS_FL(output IN) : COLOR
{
float3 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
NormalMap=normalize(NormalMap);
float3 LightV=normalize(IN.LightVec);
float3 View=normalize(IN.ViewVec);
float Normal=saturate(dot(reflect(-View,NormalMap),LightV));
Normal=pow(Normal,SpecularPow)+saturate(dot(NormalMap,LightV));
float PixelLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float3 Light=PixelLight*texCUBE(CubeLight,IN.CubeLight)*BrightNess;
return float4(Texture*(Normal*Light),Alpha);
}
//--------------
// techniques
//--------------
technique Ambient
{
pass p1
{
vertexShader = compile vs_2_0 VS();
pixelShader = compile ps_2_0 PS();
}
}
technique Light1
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
}
technique Light2
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light3
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light4
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light5
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light6
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p6
{
vertexShader = compile vs_2_0 VS_L6();
pixelShader = compile ps_2_0 PS_L6();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Ambient_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS();
pixelShader = compile ps_2_0 PS();
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light1_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light2_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light3_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light4_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light5_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}
technique Light6_FL
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass p6
{
vertexShader = compile vs_2_0 VS_L6();
pixelShader = compile ps_2_0 PS_L6();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
pass pFL
{
vertexShader = compile vs_2_0 VS_FL();
pixelShader = compile ps_2_0 PS_FL();
AlphaBlendEnable = True;
SrcBlend = One;
DestBlend = One;
}
}