open up the shader .fx file with any text editor, and look at the tweaks section... the names there should look familiar...
i'm using Evolved's normalmap.fx shader... below...
the variables LightPosition_
X will determine the respective lights positions... same with the LightRange and LightColor variables...
you can set em in the shader, or in your code (remember, all but the range are vectors)...
if you look further down, you'll see the different techniques for each light...
you can set them in your program as well...
here is the shader .fx code just in case... (i've messed with some of the variables)
//--------------------------------
// NormalMapping
//--------------------------------
// By Evolved
// http://www.vector3r.com/
//--------------------------------
//-----------------
// un-tweaks
//-----------------
matrix WorldVP:WorldViewProjection;
matrix World:World;
matrix ViewInv:ViewInverse;
//-----------------
// tweaks
//-----------------
float4 Ambient = {0.0f, 0.0f, 0.0f, 1.0f}; // final component must be 1.0 - GG
float4 LightPosition_1 = {0.0f, 50.0f, 0.0f, 1.0f};
float4 LightColor_1 = {1.0f, 1.0f, 1.0f, 1.0f};
float LightRange_1 = 55.0f;
float4 LightPosition_2 = {-50.0f, 50.0f, -50.0f, 1.0f};
float4 LightColor_2 = {1.0f, 0.0f, 0.0f, 1.0f};
float LightRange_2 = 55.0f;
float4 LightPosition_3 = {100.0f, 50.0f, 0.0f, 1.0f};
float4 LightColor_3 = {0.0f, 1.0f, 0.0f, 1.0f};
float LightRange_3 = 55.0f;
float4 LightPosition_4 = {150.0f, 50.0f, 0.0f, 1.0f};
float4 LightColor_4 = {0.0f, 0.0f, 1.0f, 1.0f};
float LightRange_4 = 55.0f;
float4 LightPosition_5 = {0.0f, 50.0f, 50.0f, 1.0f};
float4 LightColor_5 = {1.0f, 1.0f, 1.0f, 1.0f};
float LightRange_5 = 55.0f;
float4 LightPosition_6 = {50.0f, 50.0f, 50.0f, 1.0f};
float4 LightColor_6 = {1.0f, 0.0f, 0.0f, 1.0f};
float LightRange_6 = 55.0f;
float U = 1.0f;
float V = 1.0f;
float SpecularPow = 32.0f;
//-----------------
// Textures
//-----------------
texture BaseTX
<
string Name="";
>;
sampler2D Base = sampler_state
{
texture = <BaseTX>;
};
texture NormalTX
<
string Name="";
>;
sampler2D Normal = sampler_state
{
texture = <NormalTX>;
};
//-----------------
// 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;
};
//-----------------
// vertex shader
//-----------------
output VS(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
OUT.LightVec=0;
OUT.Attenuation=0;
OUT.ViewVec=0;
return OUT;
}
output VS_L1(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
output VS_L2(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
output VS_L3(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
output VS_L4(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
output VS_L5(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
output VS_L6(input IN)
{
output OUT;
OUT.OPos=mul(IN.Pos,WorldVP);
OUT.Tex=IN.UV*float2(U,V);
float3 WNor=mul(IN.Normal,World); WNor=normalize(WNor);
float3 Wtan=mul(IN.Tangent,World); Wtan=normalize(Wtan);
float3 Wbin=mul(IN.Binormal,World); Wbin=normalize(Wbin);
float3 WPos=mul(IN.Pos,World);
float3x3 TBN={Wtan,Wbin,WNor}; TBN=transpose(TBN);
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);
return OUT;
}
//-----------------
// pixel shader
//-----------------
float4 PS(output IN) : COLOR
{
float4 Texture=tex2D(Base,IN.Tex);
return Texture*Ambient; // no changes needed here - GG
}
float4 PS_L1(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_1;
return float4 ((Texture*(((Normal+Specular)*Light)+Ambient)).rgb, Texture.a); // GG
}
float4 PS_L2(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_2;
return float4 ((Texture*(((Normal+Specular)*Light))).rgb, Texture.a); // GG
}
float4 PS_L3(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_3;
return float4 ((Texture*(((Normal+Specular)*Light))).rgb, Texture.a); // GG
}
float4 PS_L4(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_4;
return float4 ((Texture*(((Normal+Specular)*Light))).rgb, Texture.a); // GG
}
float4 PS_L5(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_5;
return float4 ((Texture*(((Normal+Specular)*Light))).rgb, Texture.a); // GG
}
float4 PS_L6(output IN) : COLOR
{
float4 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(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=pow(Specular,SpecularPow);
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor_6;
return float4 ((Texture*(((Normal+Specular)*Light))).rgb, Texture.a); // GG
}
//-----------------
// techniques
//-----------------
//-----------------
// techniques
//-----------------
technique Ambient
{
pass p1
{
vertexShader = compile vs_2_0 VS();
pixelShader = compile ps_2_0 PS();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light1
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light2
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light3
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light4
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light5
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
technique Light6
{
pass p1
{
vertexShader = compile vs_2_0 VS_L1();
pixelShader = compile ps_2_0 PS_L1();
alphablendenable = true; // GG
srcBlend = srcAlpha; // GG
destBlend = invSrcAlpha; // GG
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p2
{
vertexShader = compile vs_2_0 VS_L2();
pixelShader = compile ps_2_0 PS_L2();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p3
{
vertexShader = compile vs_2_0 VS_L3();
pixelShader = compile ps_2_0 PS_L3();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p4
{
vertexShader = compile vs_2_0 VS_L4();
pixelShader = compile ps_2_0 PS_L4();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p5
{
vertexShader = compile vs_2_0 VS_L5();
pixelShader = compile ps_2_0 PS_L5();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
pass p6
{
vertexShader = compile vs_2_0 VS_L6();
pixelShader = compile ps_2_0 PS_L6();
AlphaBlendEnable = True;
SrcBlend = srcAlpha; // GG
DestBlend = One;
AlphaTestEnable = true;
AlphaFunc = Greater;
AlphaRef = 170;
}
}
all this you probably know and have done already... i just found out that when i changed the values in the shader code, the light position didn't change... but when i changed the values in my program code, it did...
so i guess it's a good idea to leave the shader alone and change the values from the program...
here's a small example of what i did to get 2 lites, using the default color in the shader for the second light, and reseting the second lights position to directly under the first one...
dbSetEffectTechnique (1,"Light2");
dbSetVector4( 1,0.0,-150.0,0.0,1.0);
dbSetEffectConstantVector(1,"LightPosition_2",1);
dbSetEffectConstantFloat( 1,"LightRange_2",300.0);
i put this in the main loop so it continually is available...
here's what it looks like with the default single light technique
here's what it looks like after adding that lil snippet... now
with 2 lights and the second one below the first
you can see the white light shining down and the red light shining from below...
hope this helps...
--Mike