This is the promised specular bumpmapping:
Code:
MATERIAL mtl_bumpspecular
{
effect=
"
#include <transform>
#include <fog>
#include <pos>
#include <normal>
#include <tangent>
float4 vecSunDir;
float4 vecColor;
texture entSkin1; // texture
texture entSkin2; // normal map
sampler sBaseTex = sampler_state { Texture = <entSkin1>; };
sampler sBump = sampler_state { Texture = <entSkin2>; };
struct out_specular
{
float4 Pos: POSITION;
float Fog: FOG;
float4 Color: COLOR;
float2 Tex: TEXCOORD0;
float2 Bump: TEXCOORD1;
float3 Normal: TEXCOORD2;
float3 Halfway:TEXCOORD3;
};
out_specular vs_specular(
in float4 inPos: POSITION,
in float3 inNormal: NORMAL,
in float2 inTex: TEXCOORD0,
in float3 inTangent: TEXCOORD2)
{
out_specular Out;
Out.Pos = DoTransform(inPos);
Out.Tex = inTex;
Out.Bump = inTex; // different coordinates required for ps_1_1
Out.Color = float4(1.0,1.0,1.0,1.0);
Out.Fog = DoFog(inPos);
CreateTangents(inNormal,inTangent);
float3 N = matTangent[2];
Out.Normal = DoTangent(N) * 0.5 + 0.5;
float3 P = DoPos(inPos);
float3 EyeDir = normalize(vecViewPos - P) - vecSunDir;
Out.Halfway = DoTangent(EyeDir) * 0.5 + 0.5;
return Out;
}
float4 ps_specular(out_specular In): COLOR
{
float4 base = tex2D(sBaseTex,In.Tex);
float3 bumpNormal = tex2D(sBump,In.Bump);
float light = saturate(dot(In.Halfway*2 - 1,bumpNormal*2 - 1));
light *= light;
light *= light;
light *= light;
light *= light;
return base *2*light;
}
technique specular
{
pass One
{
VertexShader = compile vs_1_1 vs_specular();
PixelShader = compile ps_1_1 ps_specular();
}
}
";
}
However, here's indeed the shader 2.0 model a better solution - either that, or two passes. Due to the limitation to 4 texture coordinate sets under 1.1, I can not transfer the light coordinates to the pixel shader, which limits the specular shading to a "metal" effect.
You can play with the "2" factor in the pixel shader, or return base + (0.1 + 2*light) for brightening the dark parts of the model.