rendered paste body//------- Constants --------
float4x4 World : WORLD;
float4x4 View : VIEW;
float4x4 Proj : PROJECTION;
float2 UVScale;
bool NormalMapped;
float4 LightDirection : LIGHT_DIRECTION;
float4 CameraForward : VIEW_FORWARD;
//Material Properties
float4 AmbientColor : AMBIENT_COLOR;
float AmbientPower : AMBIENT_POWER;
float4 SpecularColor : SPECULAR_COLOR;
float SpecularPower : SPECULAR_POWER;
float4 DiffuseColor : DIFFUSE_COLOR;
//Material Properties
//Refraction
bool Refraction;
float WaterHeight;
float WaterViewDepth;
float4 DeepWaterColor;
//Refraction
//Edit Mode
float3 CursorColor = {0, 0.1f, 0.4f};
float3 EditPosition;
float EditRadius;
bool EditMode;
//Edit Mode
texture DirtTexture;
texture GrassTexture;
texture RockTexture;
texture SnowTexture;
texture DirtTextureN;
texture GrassTextureN;
texture RockTextureN;
texture SnowTextureN;
sampler DirtTextureSampler = sampler_state
{
Texture = <DirtTexture>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler GrassTextureSampler = sampler_state
{
Texture = <GrassTexture>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler RockTextureSampler = sampler_state
{
Texture = <RockTexture>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler SnowTextureSampler = sampler_state
{
Texture = <SnowTexture>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler DirtTextureNSampler = sampler_state
{
Texture = <DirtTextureN>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler GrassTextureNSampler = sampler_state
{
Texture = <GrassTextureN>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler RockTextureNSampler = sampler_state
{
Texture = <RockTextureN>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
sampler SnowTextureNSampler = sampler_state
{
Texture = <SnowTextureN>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
struct VS_INPUT
{
float4 Position : Position0;
float3 Normal : Normal0;
float4 WeightOne : TexCoord0;
float4 WeightTwo : TexCoord1;
};
struct VS_INPUT_N
{
float4 Position : Position0;
float3 Normal : Normal0;
float4 Weight : TexCoord0;
};
struct VS_OUTPUT
{
float4 Position : Position0;
float4 HPosition : TexCoord0;
float3 Normal : TexCoord1;
float4 WeightOne : TexCoord2;
float4 WeightTwo : TexCoord3;
};
struct VS_OUTPUT_N
{
float4 Position : Position0;
float4 HPosition : TexCoord0;
float3 Normal : TexCoord1;
float3 Binormal : TexCoord2;
float3 Tangent : TexCoord3;
float4 Weight : TexCoord4;
};
VS_OUTPUT_N MultiTexturedNormalVertexShader( VS_INPUT_N input)
{
VS_OUTPUT_N Output;
// These estimated values should work on terrain that isn't steep,
// while steep terrain will not be fully normal mapped.
float3 Binormal = (0.0f, 0.0f, -0.5f);
float3 Tangent = (0.0f, -0.5f, 0.0f);
Output.HPosition = mul(input.Position, World);
Output.Position = mul(input.Position, mul(World, mul(View, Proj)));
Output.Normal = mul(input.Normal, World);
Output.Tangent = mul(Tangent, World);
Output.Binormal = mul(Binormal, World);
Output.Weight = input.Weight;
return Output;
}
VS_OUTPUT MultiTexturedVertexShader( VS_INPUT input)
{
VS_OUTPUT Output;
Output.HPosition = input.Position;
Output.Position = mul(input.Position, mul(World, mul(View, Proj)));
Output.Normal = mul(input.Normal, World);
Output.WeightOne = input.WeightOne;
Output.WeightTwo = input.WeightTwo;
return Output;
}
float4 MultiTexturedNormalPixelShader(VS_OUTPUT_N input) : COLOR0
{
float2 uv = (input.HPosition.xz - float2(0.5, 0.5)) * UVScale;
float4 Color = tex2D(DirtTextureSampler, uv) * input.Weight.x;
Color += tex2D(GrassTextureSampler, uv) * input.Weight.y;
Color += tex2D(RockTextureSampler, uv) * input.Weight.z;
Color += tex2D(SnowTextureSampler, uv) * input.Weight.w;
float4 NColor = tex2D(DirtTextureNSampler, uv) * input.Weight.x;
NColor += tex2D(GrassTextureNSampler, uv) * input.Weight.y;
NColor += tex2D(RockTextureNSampler, uv) * input.Weight.z;
NColor += tex2D(SnowTextureNSampler, uv) * input.Weight.w;
NColor.rgb = normalize(mul(NColor, float3x3(input.Tangent, input.Binormal, input.Normal))) * 0.5f;
float3 lightVector = -normalize(LightDirection);
float lightingFactor = saturate(dot(NColor + input.Normal, lightVector));
float3 Reflect = (lightingFactor * input.Normal) + -lightVector;
float3 specular = pow(saturate(dot(Reflect, -CameraForward)), SpecularPower);
Color.rgb *= (AmbientColor + (DiffuseColor * lightingFactor) + (SpecularColor * specular * lightingFactor)) * AmbientPower;
Color.a = 1.0f;
if(EditMode)
{
float3 delta = input.HPosition - EditPosition;
float len = length(delta);
float colorStr = clamp((EditRadius / len), 0, 1);
float3 EditColor = CursorColor * colorStr;
Color.rgb += EditColor;
}
if(Refraction)
{
if(input.HPosition.y < WaterHeight)
{
float maxDepth = WaterHeight - WaterViewDepth;
float depthWeight = 1 - clamp((input.HPosition.y) / maxDepth,0, 1);
Color.rgb -= (Color.rgb * depthWeight);
Color.rgb += DeepWaterColor.rgb * depthWeight;
}
}
return Color;
}
float4 MultiTexturedPixelShader(VS_OUTPUT input) : COLOR0
{
float2 uv = (input.HPosition.xz - float2(0.5, 0.5)) * UVScale;
float4 Color = tex2D(DirtTextureSampler, uv) * input.WeightOne.x;
Color += tex2D(GrassTextureSampler, uv) * input.WeightOne.y;
Color += tex2D(RockTextureSampler, uv) * input.WeightOne.z;
Color += tex2D(SnowTextureSampler, uv) * input.WeightOne.w;
Color += tex2D(DirtTextureNSampler, uv) * input.WeightTwo.x;
Color += tex2D(GrassTextureNSampler, uv) * input.WeightTwo.y;
Color += tex2D(RockTextureNSampler, uv) * input.WeightTwo.z;
Color += tex2D(SnowTextureNSampler, uv) * input.WeightTwo.w;
float3 lightVector = -normalize(LightDirection);
float NdL = max(0, dot(input.Normal, lightVector));
Color.rgb = NdL * Color.rgb;
Color.a = 1.0f;
if(EditMode)
{
float3 delta = input.HPosition - EditPosition;
float len = min(EditRadius, length(delta));
float colorStr = clamp((1 - (len / EditRadius)), 0, 1);
float3 EditColor = CursorColor * colorStr;
Color.rgb += EditColor;
}
if(Refraction)
{
if(input.HPosition.y < WaterHeight)
{
float maxDepth = WaterHeight - WaterViewDepth;
float depthWeight = 1 - clamp((input.HPosition.y) / maxDepth,0, 1);
Color.rgb -= (Color.rgb * depthWeight);
Color.rgb += DeepWaterColor.rgb * depthWeight;
}
}
return Color;
}
technique MultiTextured
{
pass Pass0
{
VertexShader = compile vs_1_1 MultiTexturedVertexShader();
PixelShader = compile ps_2_0 MultiTexturedPixelShader();
}
}
technique MultiTexturedNormal
{
pass Pass0
{
VertexShader = compile vs_1_1 MultiTexturedNormalVertexShader();
PixelShader = compile ps_2_0 MultiTexturedNormalPixelShader();
}
}