Here is the shader:
//--------------------------------
// NormalMapping With Fog
//--------------------------------
// By Evolved
// http://www.vector3r.com/
//--------------------------------
//-----------------
// un-tweaks
//-----------------
matrix WorldVP:WorldViewProjection;
matrix World:World;
matrix ViewInv:ViewInverse;
vector vCPS : CameraPosition;
//-----------------
// tweaks
//-----------------
float4 LightPosition = {150.0f, 150.0f, 0.0f, 1.0f};
float4 LightColor = {1.0f, 1.0f, 1.0f, 1.0f};
float LightRange = 250.0f;
float4 Ambient = {0.1f, 0.1f, 0.1f, 1.0f};
float U = 1.0f;
float V = 1.0f;
float4 fogColor = {0.1f, 0.5f, 0.5f, 1.0f};
float fogDistance = 2500.0f;
//-----------------
// Textures
//-----------------
texture BaseTX
<
string Name="";
>;
sampler2D Base = sampler_state
{
texture = <BaseTX>;
};
texture NormalTX
<
string Name="";
>;
sampler2D Normal = sampler_state
{
texture = <NormalTX>;
};
texture NormalizerTX
<
string Name = "";
>;
samplerCUBE Normalizer = sampler_state
{
Texture = <NormalizerTX>;
ADDRESSU = Clamp;
ADDRESSV = Clamp;
MagFilter = Linear;
MinFilter = Point;
MipFilter = None;
};
//-----------------
// 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;
float Fog:FOG;
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);
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-WPos;
float3 ViewPos=ViewInv[3].xyz-WPos;
OUT.Fog = 1.0f - ( length( IN.Pos - vCPS) / 5000.0f);
OUT.LightVec=mul(LightPos,TBN);
OUT.Attenuation=-LightPos/LightRange;
OUT.ViewVec=mul(ViewPos,TBN);
return OUT;
}
//-----------------
// pixel shader
//-----------------
float4 PS(output IN) : COLOR
{
float4 Texture=tex2D(Base,IN.Tex);
float3 NormalMap=tex2D(Normal,IN.Tex)*2-1;
float3 LightV=texCUBE(Normalizer,IN.LightVec)*2-1;
float3 View=texCUBE(Normalizer,IN.ViewVec)*2-1;
float Normal=saturate(dot(NormalMap,LightV));
float Specular=saturate(dot(reflect(-View,NormalMap),LightV));
Specular=Specular*Specular; Specular=Specular*Specular;
Specular=Specular*Specular;
float4 DiffuseLight=1-saturate(dot(IN.Attenuation,IN.Attenuation));
float4 Light=DiffuseLight*LightColor;
return Texture*(((Normal+Specular)*Light)+Ambient);
}
//-----------------
// techniques
//-----------------
technique NormalMapping
{
pass p1
{
FOGENABLE = (3);
FOGCOLOR = (fogColor);
vertexShader = compile vs_1_1 VS();
pixelShader = compile ps_1_4 PS();
}
}
Attached Is the easy to use and implement code
Here is the above mentioned code with some information added, just change the code in the attachment with this:
Rem Project: FoggedShader
Rem Created: 29.12.2007 13:18:26
Rem ***** Main Source File *****
Sync On : Sync Rate 60
Autocam Off
Set Camera Range 0, 0.5, 10000
Color Backdrop Rgb(128, 128, 128)
Fog On
Fog Color Rgb(128, 128, 128)
REM Make object to represent light position
Make Object Sphere 1, 10
Position Camera 0, 10, 0
GOSUB lblr_Setup
While Not escapeKey()
REM CAMERA STUFF
ax# = WrapValue(ax# + mousemovey())
ay# = WrapValue(ay# + mousemovex())
Rotate Camera ax#, ay#, 0.0
If MouseClick()=1 Then Move Camera 10
If MouseClick()=2 Then Move Camera -10
REM Visualise light position
ang# = wrapValue(ang# + 1)
z# = Sin(ang#)*(500/2.0) + (500/2.0)
fxUpdLightPos(fxNMap, 0.0, 250, z#)
Position Object 1, 0.0, 250, z#
Set Cursor 0, 0
Print "Screen Fps ",Screen Fps()
Print "Use mouse to control camera"
Print "To see the fog in action just go away from the objects and you will see"
Sync
endWhile
End
lblr_Setup:
REM Normal Map
`>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
REM Constants & Variables
#CONSTANT fxVec = 1
null = Make Vector4(fxVec)
REM NORMAL MAP
GLOBAL fxNMap, imgS As Integer
REM Load
REM NORMAL MAP IMAGES
imgS = 1 : Load Image "s.dds", imgS, 2
imgC = 2 : Load Image "c.tga", imgC
imgN = 3 : Load Image "n.tga", imgN
fxNMap = 1 : Load Effect "NormalMapWithFog.fx", fxNMap, 0
REM DEFAULT NORMAL MAP
fxUpdLightCol(fxNMap, 10, 10, 200)
fxUpdLightRng(fxNMap, 1500.0)
fxUpdLightUVM(fxNMap, 4, 4)
fxUpdLightAmb(fxNMap, 75, 75, 75)
fxUpdFogCol(fxNMap, 128.0, 128.0, 128.0)
fxUpdFogRng(fxNMap, 1000)
obj = makeObjBoxNormalMapped(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1000, 2, 1000, imgC, imgN)
obj = makeObjBoxNormalMapped(0.0, 250.0, 500.0, 0.0, 0.0, 0.0, 1000, 500, 2, imgC, imgN)
obj = makeObjBoxNormalMapped(0.0, 250.0, -500.0, 0.0, 0.0, 0.0, 1000, 500, 2, imgC, imgN)
`<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
RETURN
Function makeObjBoxNormalMapped(x#, y#, z#, rx#, ry#, rz#, sx#, sy#, sz#, c, n)
Local i As Integer : i = freeObject()
Make Object Box i, sx#, sy#, sz#
Position Object i, x#, y#, z#
Rotate Object i, rx#, ry#, rz#
fxSet(i, fxNMap)
Texture Object i, 0, c
Texture Object i, 1, n
Texture Object i, 2, imgS
endFunction i
Function freeObject()
Local i As Integer
Repeat
Inc i
Until Object Exist(i) = 0
EndFunction i
REM NORMAL MAP FUNCTIONS
Function fxSet(o As Integer, fx As Integer)
set object effect o, fx
EndFunction
Function fxUpdLightRng(fx As Integer, r As Float)
Set Effect Constant Float fx, "LightRange", r
EndFunction
Function fxUpdLightUVM(fx As Integer, u As Integer, v As Integer)
Set Effect Constant Float fx, "U", u
Set Effect Constant Float fx, "V", v
EndFunction
Function fxUpdLightPos(fx As Integer, x As Float, y As Float, z As Float)
Set Vector4 fxVec, x, y, z, 0.0
Set Effect Constant Vector fx, "LightPosition", fxVec
EndFunction
Function fxUpdLightCol(fx As Integer, r As Float, g As Float, b As Float)
Set Vector4 fxVec, r/255, g/255, b/255, 1.0
Set Effect Constant Vector fx, "LightColor", fxVec
EndFunction
Function fxUpdLightAmb(fx As Integer, r As Float, g As Float, b As Float)
Set Vector4 fxVec, r/255, g/255, b/255, 1.0
Set Effect Constant Vector fx, "Ambient", fxVec
EndFunction
Function fxUpdFogCol(fx As Integer, r As Float, g As Float, b As Float)
Set Vector4 fxVec, r/255, g/255, b/255, 1.0
Set Effect Constant Vector fx, "fogColor", fxVec
EndFunction
Function fxUpdFogRng(fx As Integer, r As Float)
Set Effect Constant Float fx, "fogRange", r
EndFunction