BigWinston

Hey,

I have a 3d terrain system. The terrain is built using a heightmap image. Then I have a large texture that I paste over the top, this covers the complete terrain.

I'd like to be able to dispose of the one large terrain texture image and use tiling and different layers for different tiles. (Texture splattering, I think this is called).

However, for now I'll be happy with just tiling my grass texture over the top of my terrain instead of it automatically scaling. Can anyone point me in the right direction to repeat and tile my texture rather than stretch to fit

Thanks



Re: XNA Game Studio Express Tiling a texture?

Fluxtah

Making a texture stretch the entire terrain is a good start, all you would need to do now is scale the texture coords in the shader. here is an example of how to do this:


sampler2D Base;
float4x4 matViewProjection : ViewProjection;
struct VS_INPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;

};

struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord : TEXCOORD0;
float2 Texcoord1 : TEXCOORD1;

};

VS_OUTPUT vs_main( VS_INPUT Input )
{
VS_OUTPUT Output;

Output.Position = mul( Input.Position, matViewProjection );
Output.Texcoord = Input.Texcoord;
Output.Texcoord1 = Input.Texcoord;
Output.Texcoord1.xy *= 2;
return( Output );

}

The input texture coordinates using the semantic TEXCOORD0 is copied to another set of texture coords with the semantic TEXCOORD1 and then multiplied on the line Output.Texcoord1.xy *= 2; this would tile the texture twice if used in the pixel shader when sampling the texture. You also need to change the texture states addressu and addressv to wrap.

hope that helps.





Re: XNA Game Studio Express Tiling a texture?

Jim Perry

Check here.




Re: XNA Game Studio Express Tiling a texture?

BigWinston

Thanks.

I've tried looking at your shader example code, I believe I now tile a texture twice over my terrain.

How would I go about tiling multiple times, i.e. dynamically pass a terrain height and width into the shader, and a tile size and then tile according to the calculated tile size over the entire terrain (with an image the same size as the tile) Is this even possible, or must I do it in the code

I've had a look at Reimers tutorials, who seems to demonstrate mirroring textures. If I were to do this in the terrain code, do I have to group primitives and divide them down into subsets to tile over I'm a little lost on how it would work in the code if I couldn't do what i wanted in the Shader.

Thanks




Re: XNA Game Studio Express Tiling a texture?

Fluxtah

You could add a new parameter to the shader, say:

float textureScale;

and set that shader parameter in your c# code, and then change the line where it does the scaling to:

Output.Texcoord1.xy *= textureScale;

You could work out some scale factor based on the dimensions of the terrain before passing it to the shader if you really wanted to do that.

The way I have done it is quite similar I have a grid of n*n terrain tiles, and my main texture coordinates span the entire terrain, and then I just copy them and scale them appropriately for each texture layer, I define the scaling in a config file, so they can be scaled to suit.





Re: XNA Game Studio Express Tiling a texture?

BigWinston

Fluxtah,

Thanks for your help. I can now get the terrain with one correctly sized tile (I am using 25.0f as a scalar).

If I move my camera over the top left corner of my terrain I can see that it has correctly created 1 tile (Tile 1 in pic below). Then the next tiles (both having an edge with the correctly textured tile) seem to have their texture as the edge of pixels from the edge with tile 1. This stretches across the whole of tiles 2 and 3. Texture 4 is just solid green (I assume the pixel color in the corner between tiles 1 and 4).

Any ideas how I can take this correct tile and map it across the whole terrain !

I have set the sampler as wrap (shown below) :

_____________________________________
| | |
| 1 | 2 |
| | |
|____________________________________
| | |
| | |
| | |
| 3 | 4 |
| | |
| | |
| | |
| | |
_____________________________________


sampler ColoredTextureSampler = sampler_state { texture = <xColoredTexture>; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = wrap; AddressV = wrap;};





Re: XNA Game Studio Express Tiling a texture?

Fluxtah

Hiya,

What I tend to do is work in powers of 2, then everything should tile nicely, I use texture sizes of 512x512 and I only scale in powers of 2 also, 25.0f would not be a suitable scale, try using 16, 32, 64, etc for scaling to ensure everything wraps uniformly.

the sampler states look fine, are you terrain tiles also power of 2 I use 33x33 vertice tiles but thats just a preference, although I do find them quite optimal size.





Re: XNA Game Studio Express Tiling a texture?

BigWinston

Hey,

I've set up my shader to tile using a power of 2 as you suggested. I didn't expect it to make much difference to my current problem though.

I may not have (although I tried!) explained my problem too well before, so here is a link to an image showing my problem : click here

And here is my shader code. I can't see anything wrong with it, although I have only been trying to learn HLSL for one week!

I'd appreciate it if you could take a look...

Thanks




Re: XNA Game Studio Express Tiling a texture?

Fluxtah

Ah, ok, thats very strange its as if your AddressU and AddressV states are set to Clamp, but I can clearly see you have set them Wrap.

I am not sure if this will directly help your problem, but I have made a few modifications, that might not make the slightest bit of difference, but just to be sure :)

I hope these changes have not broke the shader, I see your targetting vs and ps 1.1, try compiling for pixel shader 1_4 if the changes have no effect.

texture xColoredTexture;
float4x4 xWorldViewProjection;
float xTextureTileScale;

sampler2D ColoredTextureSampler = sampler_state
{
Texture = (xColoredTexture);
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
MIPFILTER = LINEAR;
ADDRESSU = WRAP;
ADDRESSV = WRAP;
};


struct VertexToPixel
{
float4 Position : POSITION0;
float2 Texcoord0 : TEXCOORD0;
float2 Texcoord1 : TEXCOORD1;
float2 Texcoord2 : TEXCOORD2;
float2 Texcoord3 : TEXCOORD3;
};

VertexToPixel SimplestVertexShader( float4 inPos : POSITION0, float2 inTexCoords : TEXCOORD0)
{
VertexToPixel Output;

Output.Position = mul(inPos, xWorldViewProjection);

Output.Texcoord0 = inTexCoords;

Output.Texcoord1 = inTexCoords;
Output.Texcoord1.xy *= xTextureTileScale;

return Output;
}

float4 OurFirstPixelShader(VertexToPixel PSIn) : COLOR0
{
// Output.Color = tex2D(ColoredTextureSampler, PSIn.Texcoord0);

float4 color = tex2D(ColoredTextureSampler, PSIn.Texcoord1);

return color;
}

technique Terrain_Render
{
pass Grass_Pass
{
VertexShader = compile vs_1_1 SimplestVertexShader();
PixelShader = compile ps_1_1 OurFirstPixelShader();
}
}





Re: XNA Game Studio Express Tiling a texture?

Fluxtah

Also to give you a bit of a jump start, I found this document very useful

http://www.jenkz.org/articles/terraintexture.htm





Re: XNA Game Studio Express Tiling a texture?

BigWinston

Hey, thanks for your help again.

I spent a while checking into the code and I realized that this line in the Pixel Shader had no place being there. I'm not quite sure why I got the results I did, but that was the problem!

Output.Color = tex2D(ColoredTextureSampler, PSIn.Texcoord1);








Re: XNA Game Studio Express Tiling a texture?

BigWinston

I take my previous post back! That wasn't the problem, it didnt do the strange segmenting thing, but it didn't perform tiling either!

I eventually traced the problem down to the image file(s) I was using to texture the terrain. I was playing round with some other files to maybe give me a clue, and some of them worked straight away!
I don't know why some images produced the same results. Maybe they were rectangular and I needed perfect squares, or something similar.

Either way it works now, thanks all for your help.






Re: XNA Game Studio Express Tiling a texture?

Fluxtah

Cool, I tend to use mipmapped dds textures, DXT1 for those without alpha and DXT3 for those with, although again this is just a preference :) I would definetly use perfect squares for terrain textures.

Still strange that it appeared to clamp the texture, it would be nice to know why this is, anyway at least it works now! :)