Played around a bit with CG again. Here’s the product of my efforts.
NOTE: the shader takes 3 seperate textures; a regular texture, a normal map texure and a black and white heightfield map.
As always comments are very welcome.
//Cg
//
//Cg profile arbvp1 arbfp1
void vshader(float4 vtx_position : POSITION,
float2 vtx_texcoord0 : TEXCOORD0,
float3 vtx_tangent0,
float3 vtx_binormal0,
float3 vtx_normal : NORMAL,
uniform float4 mspos_view,
uniform float4 mspos_light,
uniform float4x4 mat_modelproj,
out float4 l_position : POSITION,
out float2 l_texcoord0 : TEXCOORD0,
out float3 l_eyeVec,
out float3 l_lightVec)
{
l_position=mul(mat_modelproj, vtx_position);
l_texcoord0=vtx_texcoord0;
float3 dirEye = (float3)mspos_view - (float3)vtx_position;
l_eyeVec.x = dot(vtx_tangent0, dirEye);
l_eyeVec.y = dot(vtx_binormal0, dirEye);
l_eyeVec.z = dot(vtx_normal, dirEye);
float3 dirLight = (float3)mspos_light - (float3)vtx_position;
l_lightVec.x = dot(vtx_tangent0, dirLight);
l_lightVec.y = dot(vtx_binormal0, dirLight);
l_lightVec.z = dot(vtx_normal, dirLight);
}
void fshader(float2 l_texcoord0 : TEXCOORD0,
float3 l_eyeVec,
float3 l_lightVec,
uniform sampler2D tex_0,
uniform sampler2D tex_0_n,
uniform sampler2D tex_0_h,
out float4 o_color : COLOR)
{
float3 eyeT = normalize(l_eyeVec);
float3 lightT = normalize(l_lightVec);
float4 offset = tex2D(tex_0_h, l_texcoord0);
offset = offset * 0.04 - 0.02;
float2 texCoords = offset.xy * eyeT.xy + l_texcoord0;
float4 normalMap = tex2D(tex_0_n, texCoords) * 2.0 - float4(1.0,
1.0, 1.0, 1.0);
float4 tex = tex2D(tex_0, texCoords);
float3 halfAngle = normalize(normalize(l_lightVec) + normalize(l_eyeVec) / 2.0);
float4 l_brite = pow(dot((float3)normalMap, halfAngle), 60.0);
float lightProd = saturate(dot((float3)normalMap, halfAngle)+0.3);
o_color= (float4(0.2, 0.25, 0.2, 1.0) + l_brite) * tex * lightProd;
}