Hi!

I am attempting to write a multi-texture terrain shader that will apply either a rock texture or a grass texture based on the normal of the current vertex in the terrain geometry. If the vertex is "flat" (or near flat) with respect to the world space, apply the grass texture to it, if it is not flat (IE a cliff or wall) apply the rock texture to it.

As you can see from the attached screenshot, what i have is close but not quite. Im still getting grass halfway up the walls in many areas and in some areas im getting rock where the surface is flat enough it should have grass.

Screenshot: [url=http://s1126.beta.photobucket.com/user/caermundh/media/terrain_screenshot.png.html#/user/caermundh/media/terrain_screenshot.png.html?&_suid=135283034745306911133684460592][/url]

Here is the shader code i am using:

Code:
MATERIAL* drakanterrianmat = 
{   skin1 = rock_bmap;
    skin2 = grass_bmap;
    effect = "const float4x4 matWorldViewProj;
              const float4x4 matWorld;
              const float4 vecAmbient;
              const float4 vecSunDir;
              
              float4 AmbientColor = float4(1, 1, 1, 1);
              float AmbientIntensity = 1.0f;
              float DiffuseIntensity = 1.0f;
              float4 SunColor = {0.9f,0.9f,0.5f,1.0f};
              
              texture entSkin1;
              texture mtlSkin1;
              texture mtlSkin2;

              sampler ColorMapSampler=sampler_state
              {   Texture = <entSkin1>;
                  AddressU = Clamp;
                  AddressV = Clamp;
              };

              sampler RockMapSampler=sampler_state
              {   Texture = <mtlSkin1>;
                  AddressU = Wrap;
                  AddressV = Wrap;
              };
              
              sampler GrassMapSampler=sampler_state
              {   Texture = <mtlSkin2>;
                  AddressU = Wrap;
                  AddressV = Wrap;
              };

              struct VS_Input
              {   float4 InPos      :POSITION;
                  float3 InNormal   :NORMAL;
                  float2 InTex      :TEXCOORD0;
              };
              
              struct VS_Output
              {   float4 OutPos    :POSITION;
                  float2 OutTex    :TEXCOORD0;
                  float3 OutNormal :TEXCOORD1;
                  float2 OutPMTex  :TEXCOORD2;
              };
              
              struct PS_Input
              {   float2 InTex    :TEXCOORD0;
                  float3 InNormal :TEXCOORD1;
                  float2 InPMTex  :TEXCOORD2;
              };

              VS_Output vs(VS_Input input)
              {   VS_Output output;
                  output.OutPos=mul(input.InPos,matWorldViewProj);
                  output.OutNormal=normalize(mul(input.InNormal,matWorld));
                  output.OutTex = input.InTex*512;
                  output.OutPMTex = input.InTex;
                  return output;
              }

              float4 ps(PS_Input input) : COLOR0
              {   float3 Normal = normalize(input.InNormal);
                  float Orientation = dot(float3(0,1,0),Normal);
                  float4 Color = tex2D(ColorMapSampler,input.InPMTex);
                  float4 Ambient = AmbientIntensity*vecAmbient;
                  float4 Diffuse = DiffuseIntensity*saturate(dot(vecSunDir,Normal));
                  float4 ReturnTexture;
                  Diffuse *= SunColor;
                  if(Orientation>0.75)
                  {   ReturnTexture = tex2D(GrassMapSampler, input.InTex);
                  }
                  else
                  {   ReturnTexture = tex2D(RockMapSampler, input.InTex);
                  }
                  return (Ambient+Diffuse)*ReturnTexture;
              }
              
              technique ApplyTextures
              {   pass P0
                  {   VertexShader = compile vs_2_0 vs();
                      PixelShader = compile ps_2_0 ps();
                  }
              }";
}



To be honest im more than a bit fuzzy on how exatly normals work to begin with. Can someone tell me how to fix this shader so it does what its supposed to do?