///////////////
//Tweakables://
///////////////
static const float AmbientIntensity = 1.0f; // The intensity of the ambient light.
static const float DiffuseIntensity = 1.0f; // The intensity of the diffuse light.
static const float SpecularIntensity = 1.0f; // The intensity of the specular light.
static const float SpecularPower = 8.0f; // The specular power. Used as 'glossyness' factor.
static const float4 SunColor = {0.9f, 0.9f, 0.5f, 1.0f}; // Color vector of the sunlight.
/////////////////////////
//Application fed data://
/////////////////////////
const float4x4 matWorldViewProj; // World*view*projection matrix
const float4x4 matWorld; // World matrix
const float4 vecAmbient; // Ambient color.
const float4 vecSunDir; // The sun direction vector.
const float4 vecViewPos; // View position.
float3x3 matTangent; // hint for the engine to create tangents in TEXCOORD2
texture entSkin1; // Model BASE texture
texture entSkin2; // Model NORMAL MAP texture
texture entSkin3; // Model RGB COLOR MASK texture
const float4 ColorBASE; //color that will lerp where skin3 RGB==0,0,0
const float4 Color1; //color that will lerp by skin3 red value
const float4 Color2; //color that will lerp by skin3 green value
const float4 Color3; //color that will lerp by skin3 blue value
/////////////////////
//TEXTURE SAMPLERS://
/////////////////////
sampler BaseTextureSampler = sampler_state // Base Texture sampler.
{
Texture = <entSkin1>;
AddressU = Clamp;
AddressV = Clamp;
MipFilter = None; // required for mipmapping
}
sampler NormalMapSampler = sampler_state // Normal Map Texture sampler.
{
Texture = <entSkin2>;
AddressU = Clamp;
AddressV = Clamp;
MipFilter = None; // required for mipmapping
}
sampler ColorMaskSampler = sampler_state // Color Mask Texture sampler.
{
Texture = <entSkin3>;
AddressU = Clamp;
AddressV = Clamp;
MipFilter = None; // required for mipmapping
}
//////////////////
//VERTEX SHADER://
//////////////////
void ColorMasksVS( in float4 InPos: POSITION,
in float3 InNormal: NORMAL,
in float2 InTex: TEXCOORD0,
in float4 InTangent: TEXCOORD2,
out float4 OutPos: POSITION,
out float2 OutTex: TEXCOORD0,
out float3 OutViewDir: TEXCOORD1,
out float3 OutSunDir: TEXCOORD2)
{
// Transform the vertex from object space to clip space:
OutPos = mul(InPos, matWorldViewProj);
// Pass the texture coordinate to the pixel shader:
OutTex = InTex;
// Compute 3x3 matrix to transform from world space to tangent space:
matTangent[0] = mul(InTangent.xyz, matWorld);
matTangent[1] = mul(cross(InTangent.xyz, InNormal)*InTangent.w, matWorld);
matTangent[2] = mul(InNormal, matWorld);
// Calculate the view direction vector in tangent space:
OutViewDir = normalize(mul(matTangent, (vecViewPos - mul(InPos,matWorld))));
// Calculate the light direction vector in tangent space:
OutSunDir = normalize(mul(matTangent, -vecSunDir));
}
/////////////////
//PIXEL SHADER://
/////////////////
float4 ColorMasksPS(
in float2 InTex: TEXCOORD0,
in float3 InViewDir: TEXCOORD1,
in float3 InSunDir: TEXCOORD2): COLOR
{
// Read the normal from the normal map and convert from [0..1] to [-1..1] range
float3 BumpNormal = tex2D(NormalMapSampler, InTex)*2 - 1;
// Calculate the ambient term:
float4 Ambient = AmbientIntensity * vecAmbient;
// Calculate the diffuse term:
float4 Diffuse = DiffuseIntensity * SunColor * saturate(dot(InSunDir, BumpNormal));
// Calculate the reflection vector:
float3 R = normalize(2 * dot(BumpNormal, InSunDir) * BumpNormal - InSunDir);
// Calculate the specular term:
InViewDir = normalize(InViewDir);
float Specular = pow(saturate(dot(R, InViewDir)), SpecularPower) * SpecularIntensity;
// Fetch the pixel color from the color mask texture:
float4 ColorM = tex2D(ColorMaskSampler, InTex);
// Calculate percent for each mask
float PercentM1 = (ColorM.red/255);
float PercentM2 = (ColorM.green/255);
float PercentM3 = (ColorM.blue/255);
// Calculate the resulting colors for the base mixed with each mask
float4 ColorM1 = vec_lerp(ColorM1,ColorBase,Color1,PercentM1);
float4 ColorM2 = vec_lerp(ColorM2,ColorBase,Color2,PercentM2);
float4 ColorM3 = vec_lerp(ColorM3,ColorBase,Color3,PercentM3);
// Mix all masked colors (taking into account weight amongs all masks in case of overlapping)
float4 ColorM123 = vec_lerp(ColorM123,ColorM1,ColorM2,PercentM2/(PercentM1+PercentM2));
ColorM123 = vec_lerp(ColorM123,ColorM123,ColorM3,PercentM3/(PercentM1+PercentM2+PercentM3));
// Fetch the pixel color from the base texture:
float4 ColorBT = tex2D(BaseTextureSampler, InTex);
// Mix final masked result with base texture
float4 Color = vec_lerp(Color,ColorBT,ColorM123,0.5);
// Calculate final color:
return (Ambient + Diffuse + Specular) * Color;
}
//////////////
//TECHNIQUE://
//////////////
technique ColorMaskedTechnique
{
pass P0
{
VertexShader = compile vs_2_0 ColorMasksVS();
PixelShader = compile ps_2_0 ColorMasksPS();
}
}