Gamestudio Links
Zorro Links
Newest Posts
Free Live Data for Zorro with Paper Trading?
by dr_panther. 05/18/24 11:01
Change chart colours
by 7th_zorro. 05/11/24 09:25
Data from CSV not parsed correctly
by dr_panther. 05/06/24 18:50
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (7th_zorro, dr_panther), 724 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
Newest Members
Hanky27, firatv, wandaluciaia, Mega_Rod, EternallyCurious
19051 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
How do i texture terrain using the vertex normal? #411144
11/13/12 18:19
11/13/12 18:19
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
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?

Re: How do i texture terrain using the vertex normal? [Re: Caermundh] #411152
11/13/12 19:17
11/13/12 19:17
Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
Kartoffel Offline
Expert
Kartoffel  Offline
Expert

Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
I can try to fix it but it would be a great help if you upload a very small test-project
which includes a terrain file, the shader, the textures and a main script to start it.

Last edited by Kartoffel; 11/13/12 19:17.

POTATO-MAN saves the day! - Random
Re: How do i texture terrain using the vertex normal? [Re: Kartoffel] #411183
11/13/12 21:45
11/13/12 21:45
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Basically, it should be enough to only use InNormal.y in the vertex shader and pass this value to the pixel shader. There you take this value to blend (/ lerp) between the grass and rock texture.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: How do i texture terrain using the vertex normal? [Re: Superku] #411188
11/13/12 22:11
11/13/12 22:11
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
@Kartoffel:

I can put together a test level for you pretty easy, but how do I upload it to this site?

@Superku:

I basically am using InNormal.y....wait...you say use it in the Vertex shader instead of the Pixel shader? Ill give that a try and let you know what changes.

Re: How do i texture terrain using the vertex normal? [Re: Caermundh] #411189
11/13/12 22:19
11/13/12 22:19
Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
Kartoffel Offline
Expert
Kartoffel  Offline
Expert

Joined: Jun 2009
Posts: 2,210
Bavaria, Germany
I thought about triplanar texture mapping which should give pretty good results.

about the test file:
I don't think you can upload it here in the forum but you can upload it to a file hoster (like mediafire).

Last edited by Kartoffel; 11/13/12 22:19.

POTATO-MAN saves the day! - Random
Re: How do i texture terrain using the vertex normal? [Re: Kartoffel] #411194
11/13/12 23:42
11/13/12 23:42
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
Ok, heres the modified shader:

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};
              float Normal_y;
              
              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 InPosition   :POSITION;
                  float3 InNormal     :NORMAL;
                  float2 InTexture    :TEXCOORD0;
              };

              struct VS_Output
              {   float4 OutPosition :POSITION;
                  float2 OutTexture  :TEXCOORD0;
                  float3 OutNormal   :TEXCOORD1;
                  float2 OutBlendTex :TEXCOORD2;
              };
              
              struct PS_Input
              {   float2 InTexture   :TEXCOORD0;
                  float2 InNormal    :TEXCOORD1;
                  float3 InBlendTex  :TEXCOORD2;
              };
              
              
              VS_Output vs(VS_Input Input)
              {   VS_Output Output;
                  Output.OutPosition=mul(Input.InPosition,matWorldViewProj);
                  Output.OutNormal=normalize(mul(Input.InNormal,matWorld));
                  Output.OutTexture = Input.InTexture*512;
                  Output.OutBlendTex = Input.InTexture;
                  Normal_y = Input.InNormal.y;
                  return Output;
              }

              float4 ps(PS_Input Input) : COLOR0
              {   float4 Ambient = AmbientIntensity*vecAmbient;
                  float4 Diffuse = DiffuseIntensity*saturate(dot(vecSunDir,normalize(Input.InNormal)));
                  float4 Color = tex2D(ColorMapSampler,Input.InBlendTex);
                  float4 GrassTexture = tex2D(GrassMapSampler, Input.InTexture);
                  float4 RockTexture = tex2D(RockMapSampler, Input.InTexture);
                  float4 ReturnTexture = lerp(RockTexture,GrassTexture,Normal_y);
                  Diffuse *= SunColor;
                  return (Ambient+Diffuse)*ReturnTexture;
              }
              
              technique ApplyTextures
              {   pass P0
                  {   VertexShader = compile vs_2_0 vs();
                      PixelShader = compile ps_2_0 ps();
                  }
              }";
}



This does not work at all. If i use "float4 ReturnTexture = lerp(RockTexture,GrassTexture,Input.InNormal.y);" instead, i still have grass climbing halfway up the walls.

Re: How do i texture terrain using the vertex normal? [Re: Caermundh] #411195
11/14/12 00:20
11/14/12 00:20
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Well as you need the normal anyway for the diffuse part you don't have to pass it separately to the PS, sorry for the misunderstanding.
Something like
float fac = saturate(Input.InNormal.y*9); //control the sharpness of the blend with the factor ("9")
float4 ReturnTexture = lerp(RockTexture,GrassTexture,fac);
should do the trick (if I understood your issue correctly). Of course you have to tweak it a little here and there.


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Re: How do i texture terrain using the vertex normal? [Re: Superku] #411230
11/14/12 15:58
11/14/12 15:58
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
OK,

Tried that. Lerp makes the grass and stone textures blend much more nicely, but it still has grass halfway up the walls.

Re: How do i texture terrain using the vertex normal? [Re: Caermundh] #411233
11/14/12 16:24
11/14/12 16:24
Joined: Aug 2005
Posts: 238
Caermundh Offline OP
Member
Caermundh  Offline OP
Member

Joined: Aug 2005
Posts: 238
@Kartoffel:

uploaded a test level to mediafire:

http://www.mediafire.com/?7kysisresg7anvs

You can move the camera around with the arrow keys plus the left and right mouse buttons:

Left Mouse: move camera foward
Right Mouse: move camera backwards
Up Arrow: move camera up
Down Arrow: move camera down
Left arrow: strafe camera left
right arrow: strafe camera right

Re: How do i texture terrain using the vertex normal? [Re: Caermundh] #411236
11/14/12 17:36
11/14/12 17:36
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
float fac = saturate(saturate(Input.InNormal.y-0.8)*5);
float4 ReturnTexture = lerp(RockTexture,GrassTexture,fac);


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends
Page 1 of 2 1 2

Moderated by  Blink, Hummel, Superku 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1