
It is a 2 Dynamic lights, phong shader with a reflection map done with a custom system for cube maps. Obviously, it would work better if we had the cube map already implemented in Irrlicht, but until then, this is a good sustitutive IMO.
This is the Vertex shader.
Code: Select all
float3 fvLightPosition1;
float3 fvLightPosition2;
float3 fvEyePosition;
float4x4 matWorld;
float4x4 matWorldViewProjection;
float4x4 matWorldInv;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 Normal : NORMAL0;
float3 Binormal : BINORMAL0;
float3 Tangent : TANGENT0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection1: TEXCOORD2;
float3 LightDirection2: TEXCOORD3;
float3 truViewDir: TEXCOORD4;
float3 truNormal: TEXCOORD5;
};
VS_OUTPUT vs_main( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.Position = mul( IN.Position, matWorldViewProjection );
OUT.Texcoord = IN.Texcoord;
float3 RealPos = mul(IN.Position, matWorld);
float3 viewVec = fvEyePosition - RealPos;
OUT.truViewDir=viewVec;
float3 lightVec1 = fvLightPosition1 - RealPos;
float3 lightVec2 = fvLightPosition2 - RealPos;
float3 tViewVec;
float3 tLightVec1;
float3 tLightVec2;
float3 Tangent = normalize(IN.Tangent);
float3 Normal = normalize(IN.Normal);
float3 Binormal = cross( Normal , Tangent );
Tangent = cross( Normal,Binormal);
Tangent = mul( matWorldInv,Tangent );
Binormal = mul( matWorldInv,Binormal );
Normal = mul( matWorldInv,Normal );
OUT.truNormal=Normal;
tViewVec.x = dot(viewVec,Tangent);
tViewVec.y = dot(viewVec,Binormal);
tViewVec.z = dot(viewVec,Normal);
tLightVec1.x = dot(lightVec1,Tangent);
tLightVec1.y = dot(lightVec1,Binormal);
tLightVec1.z = dot(lightVec1,Normal);
tLightVec2.x = dot(lightVec2,Tangent);
tLightVec2.y = dot(lightVec2,Binormal);
tLightVec2.z = dot(lightVec2,Normal);
OUT.ViewDirection = tViewVec;
OUT.LightDirection1 = tLightVec1;
OUT.LightDirection2 = tLightVec2;
return( OUT );
}
Code: Select all
float4 LightColor1;
float4 LightColor2;
sampler2D baseMap;
sampler2D bumpMap;
sampler2D refMap;
float2 cube2uv(float3 IN){
float2 uv=0;
float3 inSQ=IN;
if(inSQ.x<0){inSQ.x=-inSQ.x;}
if(inSQ.y<0){inSQ.y=-inSQ.y;}
if(inSQ.z<0){inSQ.z=-inSQ.z;}
//We know that we will never divide by zero, so thse calculations are safe
//We map the coordinates in a texture with proportion 2:1, so we avoid rounding errors
//though it wastes the 25% of the texture space.
if(inSQ.x>=inSQ.y&&inSQ.x>=inSQ.z){
if(IN.x>0){
uv.x=0.125;
uv.y=0.25;
uv.x+=IN.z/IN.x*0.125;
uv.y-=IN.y/IN.x*0.25;
}else{
uv.x=0.625;
uv.y=0.25;
uv.x+=IN.z/IN.x*0.125;
uv.y+=IN.y/IN.x*0.25;
}
}
if(inSQ.y>inSQ.x&&inSQ.y>=inSQ.z){
if(IN.y>0){
uv.x=0.125;
uv.y=0.75;
uv.x-=IN.x/IN.y*0.125;
uv.y+=IN.z/IN.y*0.25;
}else{
uv.x=0.625;
uv.y=0.75;
uv.x+=IN.x/IN.y*0.125;
uv.y+=IN.z/IN.y*0.25;
}
}
if(inSQ.z>inSQ.x&&inSQ.z>inSQ.y){
if(IN.z>0){
uv.x=0.375;
uv.y=0.25;
uv.x-=IN.x/IN.z*0.125;
uv.y-=IN.y/IN.z*0.25;
}else{
uv.x=0.375;
uv.y=0.75;
uv.x-=IN.x/IN.z*0.125;
uv.y+=IN.y/IN.z*0.25;
}
}
return uv;
}
struct PS_INPUT
{
float2 Texcoord : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
float3 LightDirection1: TEXCOORD2;
float3 LightDirection2: TEXCOORD3;
float3 truViewDir: TEXCOORD4;
float3 truNormal: TEXCOORD5;
};
float4 ps_main( PS_INPUT IN ) : COLOR0
{
float4 base = tex2D(baseMap,IN.Texcoord);
float3 normal = tex2D(bumpMap,IN.Texcoord);
normal = normal*2-1;
float3 viewDir = normalize(IN.ViewDirection);
float3 lightDir1 = normalize(IN.LightDirection1);
float3 lightDir2 = normalize(IN.LightDirection2);
normal = normalize(normal);
float3 truNormal=normalize(IN.truNormal);
float3 halfView1 = normalize(viewDir+lightDir1);
float3 halfView2 = normalize(viewDir+lightDir2);
float3 reflVec = reflect(-IN.truViewDir,truNormal);
float4 refl = tex2D(refMap,cube2uv(reflVec));
float diffuse1 = dot(normal,lightDir1)*1;
float specular1 = pow(dot(halfView1,normal),68)*base.w;
float diffuse2 = dot(normal,lightDir2)*1;
float specular2 = pow(dot(halfView2,normal),68)*base.w;
return(saturate(base *(diffuse1+specular1)*LightColor1 +
base *(diffuse2+specular2)*LightColor2+refl*0.95));
}

But the reflection maps are better seen in a video.
http://www.youtube.com/watch?v=jwBQH1-GkyE
http://www.youtube.com/watch?v=CaeoIv0pjtQ
If you feel like using it. This chart shows how to order the map.
