Terrain Height Shader

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
alisima
Posts: 3
Joined: Fri Aug 28, 2009 10:28 am

Terrain Height Shader

Post by alisima »

I have terrain geometry (meaning every vertex has unique xz coords), and I wish to color it in the y-direction (up-down).

Like thus:
Image
In the image you can see that the bottom of the geomtry is green while at the top is goes to cyan. All is well.

Now when I move the camera around strange of artifacts pop-up, as if someone is doing "divide color by 2" or even "divide color by 4" (this happens when the faces are (sort-of) coplanar with the camera direction and when zooming out)

Image
Here is the Vertex Shader. Doesn't do much. It transforms the vertex position and outputs it, along with the reciprocal of zExtends.y and the position (untransformed).

Code: Select all

VS_OUTPUT VShade(VS_INPUT In)
{
    VS_OUTPUT Out = (VS_OUTPUT) 0;
    // apply world-view projection on vertex position
    Out.Pos = mul(mWorldViewProj,In.Pos);   
    Out.Tex0.y = 1.0 / zExtends.y;                  // zExtends.y holds the y-max of the whole terrain (while y-min is always 0.0)
    Out.Tex1 = In.Pos;
    return Out;
};      
I need the y-max of the whole terrain so I can transform the height coord of the terrain to the 0.0 - 1.0 range (which I use in my texture sampler).

Here is the vertex shader. POSITION is mandatory, TEXCOORD0 holds the reciprocal of the y-max of the terrain, TEXCOORD1 holds the (untransformed) position.

Code: Select all

PS_OUTPUT VPixel(float4 Position : POSITION, float4 TexCoord : TEXCOORD0, float4 pos : TEXCOORD1)  
{
    PS_OUTPUT Output;   
 
    float uz = saturate(pos.y * TexCoord.y);
    float4 texColor = tex2D(s_2D, float2(uz,0.0));
 
    Output.RGBColor = texColor;
    return Output;      
};
Ok, I multiply the pos.y (which I assume is interpolated by the rasterizer between the 3 vertices) with the reciprocal of the y-max of the terrain to get a scalar in the range 0.0 - 1.0 which I use to sample a texture (which in this case simply has a gradient from left to right from green to cyan).

Now, can anybody explain what is causing the artifacts??

It is strange since if I were to change the pixel shader to this (where I simply use the unity scalar as each color component):

Code: Select all

PS_OUTPUT VPixel(float4 Position : POSITION, float4 Diffuse : COLOR0, float4 TexCoord : TEXCOORD0, float4 pos : TEXCOORD1, float3 normal : TEXCOORD2)
{
    PS_OUTPUT Output;
 
    float uz = saturate(pos.y * TexCoord.y);
 
    Output.RGBColor = float4(uz,uz,uz,1.0);
    return Output;
};
I get a nice looking black to white terrain with NO artifacts....
Post Reply